質問
文字列(メソッド名)とブロック(メソッドの内容)からルビーでインスタンスメソッドを定義することは可能ですか?
私は、これは)(instance_evalを使用する必要があります想像しますが、私はまだ2つのデータ型を混在させる方法を考え出したていません。私はこれを行う方法を知りません。
- 。それは、「デフ#{文字列}」先頭にしてブロックを作成するために働くだろうように文字列とブロックの両方が動的に決定され、私のユースケースは、Baculaの設定ファイルを表すクラスです。設定ファイルには、リソースの多くの異なる種類を持つことができます。彼らはすべてのシーンの背後にある比較的複雑なデータ構造に格納している(他の理由のために、このような構造を簡素化することは私が探しているものを達成しません)。私は、リソースが名前のメソッドを経由して急速にアクセスできるようにしたいと思います。
例えば、AはBが別のものを表して設定ファイルを表します。持っている資源のディレクター、クライアント、仕事とBは、メッセージやディレクターを持っています。
Bがメッセージを持っていながら、この場合、Aは)メソッドディレクター()、クライアント()、および仕事を(持っている必要があります()と監督()。これらのそれぞれは、オブジェクトのそれぞれの設定ファイルから、関連するリソースを返します。
の私は([]メソッドを実装するように)これを行う簡単な方法があります知っているが、この時点で私は好奇心のために難しいソリューションを追求しています。の
解決
私は、あなたが探していることはモジュールのメソッドdefine_method
だと思います。あなたはそれを実行するためにclass_eval
または何か他のものを使用する必要があるので、しかし、それはプライベートです。
body = proc { self * 3 }
name = "triple"
c = Numeric
c.class_eval { define_method(name.to_sym, &body) }
3.triple # 9
と引数を持つメソッド:
body = proc { |second| [self * 3, second * 3] }
name = "triple_both"
c = Numeric
c.class_eval { define_method(name.to_sym, &body) }
puts 3.triple_both(5) # [9, 15]
(彼らは呼ばれているかEigenclass、または何でも)シングルトンオブジェクトに新しいメソッドを置くために:
body = proc { puts @meme + @meme + @meme }
name = "meme"
class SwedishChef; def initialize; @meme = "bork"; end; end
sc = SwedishChef.new
(class << sc; self; end).class_eval {
define_method(name.to_sym, &body)
}
sc.meme # borkborkbork
[EDIT(イェルクWミッターク):私は、シングルトンメソッドの例を修正した。