13

バックグラウンド

Smalltalkでは、明示的に何も返さない場合、渡されるメッセージは受信者(またはメッセージコンテキストでは「自己」)に評価されます。

たとえば、次の方法を考えます。

MyClass >> myMethod
  Transcript show: 'hello'; cr.

これを評価する(「print-it」を行う):

| myInstance |
myInstance := MyClass new.
myInstance myMethod.

<print-it>が最後の呼び出しまで実行された場合、結果はインスタンス自体になります。

質問

  • なぜこれがこのように設計されたのですか?
  • その背後にある考え方は何ですか?
  • 哲学的背景は何でしたか?
  • それからの実際的な利点は何ですか?メソッドの連鎖を容易にするためですか?
4

5 に答える 5

17

非常に単純な理由の1つはまだ述べられていません。仮想マシンでは、自己を返す方が他のオブジェクトを返すよりも簡単で効率的です。

Smalltalkバイトコードはスタックマシンを実装します。つまり、引数はレジスタに入れるのではなく、スタックにプッシュすることによって渡されます。メソッドシグニチャにリストされている引数に加えて、メッセージの受信者である非表示の引数が常に渡されます。したがって、単項メソッド(引数のないメソッド)の場合でも、レシーバーがスタックにプッシュされてからメソッドが実行され、スタック上のレシーバー値は、メソッドが「自己」を認識する方法です。明示的なreturnステートメントが指定されていない場合に「self」を返すことにより、VMは「self」oopをスタックに残すことができ、少なくとも1つのメモリストア操作を節約できます。したがって、効率と単純さの観点から、「自己」を返すことは最もエレガントなことです。

于 2012-12-30T15:40:08.913 に答える
8

Smalltalk-80のBlueBook(The Language and its Implementation )は、デフォルトでレシーバーを返す理由については何も述べていません。

ただし、27ページ(「戻り値」のセクション)には、次のような引用があります。

「送信者に情報を返す必要がない場合でも、受信者は常にメッセージ式の値を返します。戻り値は、メッセージへの応答が完了したことを示します。(...)」

Smalltalkでは、メソッドはメッセージ送信によってアクティブ化されるため、メッセージの完全なラウンドトリップが発生することに注意してください(MessageNotUnderstood例外で終了する場合があります)。メッセージ送信の概念は最も重要です。

メッセージの意図に応じて何を返すかについてはいくつかの良い習慣のパターンがありますが、それは別の話の主題です。

于 2012-12-27T02:11:49.847 に答える
6

私はsmalltalkの作成者ではありませんが、それが最善の方法のようです。

たとえば、実行する場合:

var := myInstance myMethod.

質問は次のとおりです。あなたは何varになりたいですか?1つのオプションはですnilnilただし、定義済みのオブジェクトを操作していて、実際には未定義のオブジェクトであるため、少し混乱します。myInstanceしたがって、myMethodに割り当ててvar、途中でmyMethodを呼び出すだけで処理できます。また、これはおそらくの省略形として扱うことができます

 var := myInstance myMethod; yourself.

内部から見ると、オブジェクト自体が利用できるすべてのデータから、おそらく最も適切なものもselfです。繰り返しになりnilますが、返品することはできますが、以前に意見を述べました。

Smalltalkには、何も返さないvoidメソッドのようなものはなく、型チェックもありません。したがって、メソッドは何かを返す必要があります。オブジェクトが言うように:

私は常に自分自身について知っているので、デフォルトで任意のメソッド呼び出しに対して自分自身を返すことができます。他の何かを返したい場合は、この動作を再定義できます。

nil個人的には、返品も良いと思います。Objective-Cアプリケーションはnil非常に頻繁に使用するものですが、Smalltalkはこのように作成されており、非常に優れたソリューションだと思います。

于 2012-12-27T00:55:02.337 に答える
6

メソッドは、いくつかの理由でデフォルトで自己を返します。

  1. Smalltalkメソッドは何かを返す必要があります
  2. 自己は返すのが最も簡単なオブジェクトです
  3. 自己は戻るのに最も速いオブジェクトです
  4. 自己を返すことで、いくつかのデザインパターンが自然に機能するようになります

#4についてもう少し説明しましょう。オブジェクト初期化の一般的なパターンの1つは、次のようなクラスの新しいメソッドを定義することです。

new
   ^super new initialize

このパターンは、自己を返す初期化に依存します。ただし、初期化メソッドの最後に^selfを追加するのは通常ではありません。メソッドはとにかく自分自身を返すので、それは不要です。

結局、何かを返さなければならないことを考えると、デフォルトでは自己を返すことは自然な選択です。

于 2013-01-05T01:45:12.630 に答える
0

Javaから来て、未定義の戻り値を処理するときのNullPointExceptionsを知っています。さらに、コードはあちこちでnullの条件付きチェックを実行する必要があります。

したがって、Smalltalkで送信されるすべてのメソッド呼び出しまたはメッセージの戻り値を見つけることができてうれしかったです。すべてのメソッドに何らかの値を返すことにした場合は、デフォルト値を尋ねようとしています。オブジェクト自体(自己)は、デフォルト値として使用する非常に自然な方法です。または、逆に質問します。より良い戻り値は何でしょうか。

于 2012-12-27T15:12:50.837 に答える