I'm doing this and it works:
我这样做是有效的:
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"
But calling m.to_proc
is not working...
但是调用m.to_proc不起作用......
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>>
I want to know why these two examples are different and how to make it work with to_proc
我想知道为什么这两个例子是不同的,以及如何使它与to_proc一起使用
1 个解决方案
#1
0
In the second snippet, you are calling m
, which returns the result of calling value
, which is undefined. (And even if if were somehow magically calling B#value
, then B#value
returns a String
and String
s don't respond to to_proc
, so you would get a NoMethodError
there.) In the first snippet, you call m
, which returns a Proc
.
在第二个片段中,您正在调用m,它返回调用value的结果,该结果是未定义的。 (即使如果以某种方式神奇地调用B#值,那么B#值返回一个字符串并且字符串不响应to_proc,所以你会得到一个NoMethodError。)在第一个片段中,你调用m,它返回一个PROC。
It looks like you are trying to pass the method m
itself instead of the result of calling it. In Ruby, methods aren't objects, so you can't just grab them and pass them around (and even if methods were objects, then m
is still the syntax for calling m
, not for referencing it). You have to ask Ruby's reflection API for a reflective proxy for the method first, using the Object#method
method, which returns a Method
object representing the method:
看起来你试图传递方法m本身而不是调用它的结果。在Ruby中,方法不是对象,所以你不能只抓住它们并传递它们(即使方法是对象,那么m仍然是调用m的语法,而不是用于引用它)。您必须首先使用Object#方法方法向Ruby的反射API请求该方法的反射代理,该方法返回表示方法的Method对象:
@context.instance_eval(&method(:m).to_proc)
Note that the call to to_proc
is completely redundant here, since &
will call to_proc
anyway if the argument isn't a Proc
already. (You may have seen something like foo.map(&:bar)
before, which will invoke Symbol#to_proc
.)
请注意,对to_proc的调用在这里是完全冗余的,因为如果参数不是Proc已经将调用to_proc。 (您之前可能已经看过类似foo.map(&:bar)的内容,它将调用Symbol#to_proc。)
@context.instance_eval(&method(:m))
#1
0
In the second snippet, you are calling m
, which returns the result of calling value
, which is undefined. (And even if if were somehow magically calling B#value
, then B#value
returns a String
and String
s don't respond to to_proc
, so you would get a NoMethodError
there.) In the first snippet, you call m
, which returns a Proc
.
在第二个片段中,您正在调用m,它返回调用value的结果,该结果是未定义的。 (即使如果以某种方式神奇地调用B#值,那么B#值返回一个字符串并且字符串不响应to_proc,所以你会得到一个NoMethodError。)在第一个片段中,你调用m,它返回一个PROC。
It looks like you are trying to pass the method m
itself instead of the result of calling it. In Ruby, methods aren't objects, so you can't just grab them and pass them around (and even if methods were objects, then m
is still the syntax for calling m
, not for referencing it). You have to ask Ruby's reflection API for a reflective proxy for the method first, using the Object#method
method, which returns a Method
object representing the method:
看起来你试图传递方法m本身而不是调用它的结果。在Ruby中,方法不是对象,所以你不能只抓住它们并传递它们(即使方法是对象,那么m仍然是调用m的语法,而不是用于引用它)。您必须首先使用Object#方法方法向Ruby的反射API请求该方法的反射代理,该方法返回表示方法的Method对象:
@context.instance_eval(&method(:m).to_proc)
Note that the call to to_proc
is completely redundant here, since &
will call to_proc
anyway if the argument isn't a Proc
already. (You may have seen something like foo.map(&:bar)
before, which will invoke Symbol#to_proc
.)
请注意,对to_proc的调用在这里是完全冗余的,因为如果参数不是Proc已经将调用to_proc。 (您之前可能已经看过类似foo.map(&:bar)的内容,它将调用Symbol#to_proc。)
@context.instance_eval(&method(:m))