[英]Ruby: different values of self inside lambda when using instance_eval(&lambda) vs instance_eval { lambda.call }
I want to call a lambda changing it's self value.我想调用一个 lambda 来改变它的自我价值。 Searching for it, I arrived at
instance_exec
, which was supposed to get the job done.搜索它,我到达了
instance_exec
,它应该完成工作。
However, after 1+ hour studying an example, I found this behavior I can't explain:但是,经过 1 个多小时的学习示例后,我发现这种行为无法解释:
class Dummy
class << self
attr_accessor :my_lambda
end
self.my_lambda = proc { self }
def test
self.class.my_lambda.call
end
def test1
instance_eval(&self.class.my_lambda)
end
def test2
instance_eval { self.class.my_lambda.call }
end
end
Dummy.new.test
=> Dummy # I was expecting this, returns the class, lexical scope (where `self` was defined)
Dummy.new.test1
=> #<Dummy:0x00007fe982f8b678> # I was expecting this, `self` changed to the receiver of `instance_eval`, which is the instance, so `self` returned the instance.
Dummy.new.test2
=> Dummy # I can't understand this, at all. Why isn't it the same as test1?
So, why do we get different results from instance_eval(&self.class.my_lambda)
vs instance_eval { self.class.my_lambda.call }
?那么,为什么我们从
instance_eval(&self.class.my_lambda)
和instance_eval { self.class.my_lambda.call }
得到不同的结果?
Also, since we're at the subject of calling Lambdas ... if I change the class level variable to this:此外,由于我们正在调用 Lambdas ......如果我将类级别变量更改为:
self.my_lambda = lambda { self }
then Dummy.new.test1 throws an exception ArgumentError: wrong number of arguments (given 1, expected 0)
, which I also can't understand why, since I know lambdas are strict about argument numbers, but we didn't pass any when we used instance_eval(&self.class.my_lambda)
然后 Dummy.new.test1 抛出异常
ArgumentError: wrong number of arguments (given 1, expected 0)
,我也不明白为什么,因为我知道 lambdas 对参数数量有严格的限制,但我们没有通过任何时候我们使用了instance_eval(&self.class.my_lambda)
Amazingly how, right away after writing this long question, I managed to answer it myself in one extra minute.令人惊讶的是,在写完这个长问题后,我立即设法在多一分钟内回答了它。 I needed a rubber duck.
我需要一只橡皮鸭。 Anyways.
无论如何。
I misunderstood instance_eval
.我误解了
instance_eval
。 It "Executes the given block within the context of the receiver (obj)."它“在接收者(obj)的上下文中执行给定的块。”
So, the given block in #test2
instance_eval { self.class.my_lambda.call }
was, indeed, executed with self
set to the instance, but the lambda was still called within it, which doesn't change it's self.因此,
#test2
instance_eval { self.class.my_lambda.call }
的给定块确实是在将self
设置为实例的情况下执行的,但仍然在其中调用了 lambda,这不会改变它的自身。
However, in #test1
, the ampersand &
changed the proc to a block, and then it was passed to instance_eval
, so it was the proc's own body that was executed with the self
changed.然而,在
#test1
,连字符&
改变PROC到块,然后将其传递给instance_eval
,所以这是PROC自己的身体,将其与执行的self
改变。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.