Provide value for self when using Proc#call
When using Proc#call to call a lambda function in Ruby, self
always ends up with the value that it had when the function was defined, rather than the value it has when the function is called, for example:
$p = lambda { self }
class Dummy
def test
$p.call
end
end
d = Dummy.new
> d.test
=开发者_运维知识库> main
Calling test
returns main
, when what I intended it to return is #<Dummy:0xf794>
- an instance of Dummy
, which was the value of self
at the point in the code where I called $p
.
In Javascript, I would just pass the object that I want to be the "callee" as the first argument to call
. Is there any such functionality in Ruby, allowing me to set an arbitrary object, or at least the current value of self
, as the new value for self
when I call a Proc
?
You're looking for instance_eval, which evaluates a lambda in the context of the calling object.
>> $p = proc { self }
=> #<Proc:0x95cece4@(irb):1 (lambda)>
>> class Dummy
>> def test
>> $p.call
>> end
>>
>> def test1
>> instance_eval(&$p)
>> end
>> end
>> d = Dummy.new
=> #<Dummy:0x946f7c8>
>> d.test
=> main
>> d.test1
=> #<Dummy:0x946f7c8>
You may want to use instance_exec because it allows you to pass arguments to the block whereas instance_eval does not.
def eval_my_proc_with_args(*args, &block)
instance_exec(*args, &block)
end
lambda defines a closure which means it will encapsulate the environment it had when it was defined. If you want self to be the caller just define a regular method or better yet use a block.
精彩评论