3

私は、実行時にメソッドが動作する方法を変更することがコアとなる予定のプロジェクトを開始しました。私はではありません。では、実際の効果は似ていますが、「シャドーワンの別の方法」のようなより高いレベルのオブジェクト指向の概念について話しています。私は後だどのようなプログラミング言語を使って、メソッド内の命令のシーケンスを操作できますか?

の重要な特性は以下のとおりです。

  • が、私は、新しい表現を追加し、既存の式を削除、または式のいずれかを変更することができるようにする方法を変更することができなければならないことその中で起こる。

  • メソッドを変更した後、そのメソッドを後で呼び出すと、新しい操作シーケンスが呼び出されます。 (言語は私に新しいメソッドを再バインド/アンバインドする方法を提供し、方法をバインドするのではなく一つ一つの時間を評価した場合。または、)

  • 理想的には、私は言語(例えばの原子単位を操作したいです、 "オブジェクトbarのメソッドfooを呼び出す")であり、アセンブリを直接(例えば、 "これらの3つのパラメータをスタックにポップする)"ではありません。言い換えれば、私が作った操作が言語上意味的に意味のあるものであるという高い確信を得たいと思っています。しかし、私が得ることを取るつもりです。

あなたが候補言語がこれらの基準を満たしているかどうかわからない場合は、ここでは簡単なリトマス試験があります:

あなたは別の方法がどのcleanと呼ば書き込むことができます。

  • は受け入れ方法m入力として

  • は別の方法を返します m2は、mと同じですが、あなたの言語(プット、System.Console.WriteLnの印刷・ツー・標準出法への呼び出しが含まれていないよう

  • と同じ動作を行い、printlnなど)?

私は今、いくつかの予備調査を行い、最強の候補であるかを把握したいと思います。私がしたいことを実行する実用性と同じくらい、大きくて活発なコミュニティーを持つことは、私にとって重要です。バイトコードを直接操作するのは、一般的に公開される操作ではないため、ここではいくつかの偽造されていない領域があるかもしれないことを認識しています。

私にはどのような選択肢がありますか?可能であれば、あなたが推奨する1つ以上の言語でおもちゃの例を提供できますか、最近の例を教えてください。


アップデート:私はこの後だ理由は、私は新しい情報に応じて、実行時に自分自身を変更することのできるプログラムを書きたいと思いということです。この変更は、単なるパラメータや設定可能なデータを超えて、本質的な進化した動作の変化になります。 (いいえ、私はウイルスを書いていません。;))

+0

明らかに、*既存*メソッドの命令を動的に変更したいですか? (すなわち、オンザフライで* new *メソッドの実装を一緒にスローしないでください) –

+1

@Kirk Woll:言語が私の目標をどのように満たしているかという実装の詳細については特に気にしません。私は私が後にしている主要な特性を強調するために少し質問を明確にしました。 –

答えて

1

まあ、.NETとExpressionライブラリを使用して式を構築できます。あなたがメモリ内のコマンドの表現を構築することができ、操作、トラバースなどのための優れたライブラリサポートがあるので、私は本当にあなたの最善の策だと思うと思う。

+2

これは、私は_build_式を可能にします、はい。しかし、私は_既存のメソッドをruntime_でアンバインドしてから、その後に私の作成した式を持つ新しいメソッドでそれを再バインドできますか? –

+2

@ john-feminella: "メソッド"のアイデアを削除し、代わりにデリゲートを使用します。これにより、実行時に "メソッド"(デリゲート)を変更できるので、 "メソッド"の呼び出しで既存の実装ではなく新しい/更新された実装が使用されます。 .NET 4.0 System.Dynamic.DynamicObjectと組み合わせると、メソッドのように見えるが、要求どおりに更新可能なものを持つことができます。 – jonp

+0

@jonp:これは非常に魅力的なアプローチのようです。これを私の研究対象リストに追加します。 –

0

Javaでは多くの専門家のフレームワークがオープンソースASM frameworkを使用している。
Hereは、ASMを含む有名なJavaアプリケーションとライブラリのリストです。

数年前BCELも非常によく使われました。

1

まあ、と実際にはの強力なマクロサポート(特にリスプ)を持つ言語が対象となります。

本当にこれを深くする必要がありますか?私はあなたが何をしようとしているのか分からないが、実際にはメタプログラミングに深く関わることなくそれをエミュレートできると思う。たとえば、メソッドを使用して操作する代わりに、関数のコレクションを使用します(状態を共有する何らかの方法、たとえば、それぞれに渡されたオブジェクト保持状態など)。

+0

私はLispが良い選択であることに同意します。間違いなく私の研究リストに載っています。操作するメソッドに任意の内容が含まれ、任意の(しかし意味的に有効な)方法で操作する必要があるため、制限付きメタプログラミングの提案が十分であるかどうかは不明です。 –

1

Groovyがこれを行うことができます。例えば

class Foo { 
    void bar() { 
     println "foobar" 
    } 
} 

Foo.metaClass.bar = {-> 
    prinltn "barfoo" 
} 

または私は、変更、削除、または方法からの発現を追加して、後続の呼び出しで使用することができ、このアプローチを使用する他のインスタンス

fooInstance.metaClass.bar = {-> 
    println "instance barfoo" 
} 

に影響を与えることなくFOOの特定例えば

新しい方法。 Groovyメタクラスではかなりのことができます。

+0

それは私が望むものと全く同じではありません。これは、1つのメソッドが同じ名前の別のメソッドと_replaced_できることを示しています。しかし、私が望むのは、 'bar'を操作する能力です。単純なリトマステストとして、既存のメソッドを受け入れ、元のメソッドからの 'println'文だけを持つ新しいメソッドを生成する' capture_printlns'メソッドを書くことが可能でなければなりません。 –

0

実際の実行時の変更を可能にする言語/環境があります(Common Lisp、Smalltalk、Forthなど)。あなたがしていることを本当に知っている場合は、そのうちの1つを使用してください。さもなければ、あなたのコードの進化する部分にインタープリタパターンを単純に採用することができます。あらゆるOOや関数型言語で可能です(そして些細なことです)。

+0

私はインタプリタのパターンを知っています。しかし、ここでそれを使うのは大した過労ではないでしょうか?私は一連の操作を操作するために、小さな形で言語の内部構造を繰り返し実装する必要はありません。 –

+0

唯一の関心事がシーケンスである場合は、使用可能なシーケンスプリミティブのみで言語を実装できます。この種のミニインタープリタは、10行のC#またはJavaで実装できます。実行時にコンパイラにコードを渡すよりもはるかに簡単です。 –

+0

いいえ、私は言語の機能の全範囲を必要とします。そのため、これを公開する言語が必要なので、言語自体の内部で自己修正コンパイラを実装する必要はありません。 (一部の言語では可能ではないかもしれません) –

関連する問題