オブジェクトのメソッドの実装を、ユーザーが指定するブロックに置き換えたいと思います。 JavaScriptでは、これは容易に達成される:Rubyのオブジェクトのメソッド実装を動的に置き換えます
function Foo() {
this.bar = function(x) { console.log(x) }
}
foo = new Foo()
foo.bar("baz")
foo.bar = function(x) { console.error(x) }
foo.bar("baz")
C#では、それはまた
class Foo
{
public Action<string> Bar { get; set; }
public Foo()
{
Bar = x => Console.WriteLine(x);
}
}
var foo = Foo.new();
foo.Bar("baz");
foo.Bar = x => Console.Error.WriteLine(x);
foo.Bar("baz");
非常に簡単です。しかし、どのように私はRubyで同じことを行うことができますか?
:私はインスタンス変数にラムダを格納し、この方法は、ラムダを呼び出しますが、私は本当にオーバーヘッドと構文class Foo
def initialize
@bar = lambda {|x| puts x}
end
def bar x
@bar.call x
end
def bar= blk
@bar = blk
end
end
foo = Foo.new
foo.bar "baz"
foo.bar= lambda {|x| puts "*" + x.to_s}
foo.bar "baz"
のように私はそのような構文を持っているしたいと思いませんソリューションを持っています
foo.bar do |x|
puts "*" + x.to_s
end
foo.bar "baz"
私は、次のコード
class Foo
def bar x = nil, &blk
if (block_given?)
@bar = blk
elsif (@bar.nil?)
puts x
else
@bar.call x
end
end
end
を思い付いた。しかし、これは複数のパラメータのためのちょっと醜いです、まだ「右」を感じることはありません。私はまた、set_barメソッドを定義することができますが、私はどちらか好きではありません:)。
class Foo
def bar x
if (@bar.nil?)
puts x
else
@bar.call x
end
end
def set_bar &blk
@bar = blk
end
end
そこで質問です:welldan97のアプローチの作品@ 、しかし、私は、ローカル変数のスコープ、すなわちを失う:より良い方法これを行うために行うそうでない場合、どのような方法あなたは
編集を好むがあります
prefix = "*"
def foo.bar x
puts prefix + x.to_s
end
は機能しません。私はそれが働くためにラムダをしなければならないと思いますか?
あまりにも簡単でしょう\ * facepalm \ * :) – kev
hmm、私はローカル変数、すなわち 'prefix =" * "; def foo.bar x;接頭辞+ x.to_sを入れます。最後には動作しません:/ – kev
@ welldan97、どうすれば "setter"メソッドを特定のオブジェクトに置き換えることができますか? – gaussblurinc