2017-11-17 8 views
0

私はこれをやっているし、それが動作します:Proc.newではなく、to_procでinstance_evalを呼び出す際にエラーが発生するのはなぜですか?

class B 
    def value 
    "X" 
    end 
end 

class A 
    def initialize(context) 
    @context = context 
    end 

    def m 
    Proc.new do 
     value 
    end 
    end 

    def execute 
    @context.instance_eval(&m) 
    end 
end 

A.new(B.new).execute #=> "X" 

しかし​​を呼び出すと、

class B 
    def value 
    "X" 
    end 
end 

class A 
    def initialize(context) 
    @context = context 
    end 

    def m 
    value 
    end 

    def execute 
    @context.instance_eval(&m.to_proc) 
    end 
end 

A.new(B.new).execute #=> NameError: undefined local variable or method `value' for #<A:0x007fae2ab02040 @context=#<B:0x007fae2ab02108>> 

...働いていない私は、この2つの例が異なっており、それを作るためにどのように理由を知りたいですto_proc

答えて

0

2番目のスニペットでは、を呼び出した結果を返すmを呼び出しています、これは未定義です。 (さらに何とか魔法B#valueを呼び出した場合場合、B#valueはあなたがそこにNoMethodErrorになるだろうのでStringString sが、to_procに応答しない返されます。)最初のスニペットでは、Procを返す、mを呼び出します。

mメソッドを呼び出すのではなく、そのメソッドを渡そうとしているようです。 Rubyではメソッドはオブジェクトではないので、メソッドを取得して渡すことはできません(メソッドがオブジェクトであっても、mはそれを参照するのではなく、mを呼び出す構文です)。あなたは、メソッドを表すMethodオブジェクトを返しますObject#method方法を使用して、第一の方法のための反射プロキシのRubyのリフレクションAPIを依頼する必要があります。

@context.instance_eval(&method(:m).to_proc) 

to_procへの呼び出しは、ここに完全に冗長であることに注意してください、&ので、引数がProcではない場合は、to_procと表示されます。 (あなたがSymbol#to_procを起動する前foo.map(&:bar)ようなものを、見ている可能性があります。)

@context.instance_eval(&method(:m)) 
+0

申し訳ありませんが、私はブロックにPROCを変換するために「&」の前に 'm.to_proc'を逃し、まだ動作しません。 – Leantraxxx

関連する問題