Ruby で自己変更コードを実行することはめったにありませんが、ときどきあります。
使用しているデータ (遅延キャッシュなど) が適切に初期化されているかどうかがよくわからないメソッドがある場合があります。したがって、メソッドの開始時にデータが適切に初期化されているかどうかを確認してから、初期化する必要があります。ただし、実際にはその初期化を 1 回だけ行う必要がありますが、毎回確認します。
そのため、初期化を行い、それ自体を初期化コードを含まないバージョンに置き換えるメソッドを作成することがあります。
class Cache
def [](key)
@backing_store ||= self.expensive_initialization
def [](key)
@backing_store[key]
end
@backing_store[key]
end
end
しかし、正直なところ、それだけの価値はないと思います。実際、恥ずかしいことに、その1 つの条件が実際に違いを生むかどうかを実際にベンチマークしたことはありません。(積極的に最適化するプロファイル フィードバック駆動型の JIT コンパイラを使用した最新の Ruby 実装では、おそらくそうではありません。)
「自己変更コード」をどのように定義するかによって、これが必要な場合とそうでない場合があることに注意してください。現在実行中のプログラムの一部を置き換えるので、…</p>
編集:考えてみると、その最適化はあまり意味がありません。とにかく、高価な初期化は一度だけ実行されます。変更によって回避される唯一のことは、条件付きです。小切手自体が高価な例を挙げたほうがいいのですが、思いつきません。
しかし、私は自己変更コードのクールな例を考えました: Maxine JVMです。Maxine は、完全に Java で記述された Research VM (開発者が互換性テストスイートを実行しないため、実際に「JVM」と呼ぶことは技術的に許可されていません) です。現在、それ自体で書かれた JVM はたくさんありますが、Maxine は、それ自体で動作することを私が知っている唯一のものです。これは非常に強力です。たとえば、JIT コンパイラは、それ自体を JIT コンパイルして、JIT コンパイルするコードのタイプに適合させることができます。
自己プログラミング言語用の VM であるKlein VMでも、非常によく似たことが起こります。
どちらの場合も、VM は実行時にそれ自体を最適化し、再コンパイルできます。