web-dev-qa-db-ja.com

Smalltalkの「になる」にはどのような用途がありますか?

become: Smalltalkのメッセージは、あるオブジェクトを別のオブジェクトに変更し、そのオブジェクトへのすべての参照に影響を与えます。

この言語機能にはどのような用途がありますか?実際のコードで使用されますか?それは単なる好奇心ですか?それを使用することは良い/悪い習慣と考えられていますか?

12
dpk

Gilad Bracha について話しますbecome:ある程度の長さ:

Smalltalkの最もユニークで強力な機能の1つは、Smalltalkコミュニティ以外ではあまり知られていません。これは、次のように呼ばれる小さなメソッドです。

何が起こるか:その受信者とその議論のアイデンティティを交換することです。つまり、後

aになる:b

呼び出しポイントの前にaで示されるオブジェクトへのすべての参照は、bで示されるオブジェクトを参照し、その逆も同様です。

これを内部化するために少し時間をかけてください。あなたはそれを些細なものとして誤解するかもしれません。これは、2つの変数を交換することではありません。文字通り、あるオブジェクトが別のオブジェクトになることです。この機能を備えた他の言語は知りません。それは巨大な力と危険の特徴です。

永続オブジェクトをサポートするように言語を拡張するタスクを検討してください。オブジェクトをディスクからロードしたいが、それが参照するすべてのオブジェクトを推移的にロードしたくないとします(そうでない場合、それは単なるオブジェクトの逆シリアル化です)。つまり、オブジェクト自体をロードしますが、直接参照をロードする代わりに、それらをハスクオブジェクトに置き換えます。

殻は、2次ストレージ上の実際のデータの代わりになります。そのデータは遅延して読み込まれます。実際に殻のメソッドを呼び出す必要がある場合、そのdoesNotUnderstand:メソッドは対応するデータオブジェクトをディスクからロードします(ただし、推移的ではありません)。

次に、behas:を実行して、殻へのすべての参照を新しくロードされたオブジェクトへの参照で置き換え、呼び出しを再試行します。

一部の永続化エンジンはこの種のことを何十年も行ってきましたが、通常、表現への低レベルのアクセスに依存していました。なる:ソースコードレベルでこれを行うことができます。

これをJavaで実行します。または別の動的言語でも。この方法で一般的な先物、つまり怠惰を実行できることがわかります。すべて、実装の仕組みへの特権アクセスがありません。また、スキーマの進化にも役立ちます。たとえば、インスタンス変数をクラスに追加する場合などです。必要に応じて、すべてのインスタンスを「再形成」できます。

もちろん、何気なく使ってはいけません。これにはコストがかかりますが、多くの実装では法外な場合があります。 Smalltalkの初期の段階では、すべてのオブジェクトがオブジェクトテーブルによって間接的に参照されていたため、安価になりました。オブジェクトテーブルがない場合、become:はガベージコレクターと同様の方法でヒープをトラバースします。あなたが持っているメモリが多いほど、より高価になります:になります。

オブジェクトテーブルがあると、ストレージが占有され、アクセスが遅くなります。しかし、それはあなたにかなりの柔軟性を買います。ハードウェアのサポートにより、パフォーマンスの低下が緩和される可能性があります。利点は、オブジェクトテーブルを介して間接参照のコストを前もって支払うことをいとわない場合、多くの難しい問題がかなり扱いやすくなることです。覚えておいてください:コンピュータサイエンスのすべての問題は、追加の間接レベルで解決できます。たとえば、アレックスウォースには、このカテゴリに当てはまる興味深い作品がいくつかあります。

になる:いくつかのバリエーションがあります-1つの方法:オブジェクトAのIDを別のオブジェクトBのIDに変更し、Aへの参照がBを指すようにします。 Bへの参照は変更されません。多くの場合、次のことを行うと便利です:一括-配列内のすべてのオブジェクトのIDを(単方向または双方向に)変換します。グループになる:魔法をアトミックに実行することは、たとえば、システムにリフレクトアップデートを実装するのに最適です。クラスとそのインスタンスのセット全体を一度に変更できます。

タイプセーフになることも考えられます。 2つの方法になります:AのタイプがBのタイプと同じである場合にのみタイプセーフになりますが、1つの方法になります:新しいオブジェクトが古いオブジェクトのサブタイプである必要があるだけです。

オブジェクトテーブルを持つことが実際に良いことかどうかを再検討するときかもしれません。

実際に得られるのは、メタプログラミングに相当する遅延ロードの形式です。 Brachaが指摘するように、これは非常に便利ですが、パフォーマンスに重大な影響を与える可能性があるため危険でもあります。

11
World Engineer

あまり使われていません。私が開いているPharo 5の画像には、#become:の送信者が9人いて、そのうち7人が単体テストを行っています。コンパイラーのコード生成およびFuelシリアライゼーションライブラリーで使用され、プロキシーをそのコンテンツで置き換えます。

2