[英]Ruby lambda's proc's and 'instance_eval'
当我将lambda作为instance_eval
传递给instance_eval
,它似乎传递了一个额外的参数:
lamb = -> { puts 'hi' }
proc = Proc.new { puts 'hi' }
instance_eval(&lamb)
# >> ArgumentError: wrong number of arguments (given 1, expected 0)
# from (irb):5:in `block in irb_binding'
# from (irb):7:in `instance_eval'
instance_eval(&proc)
# => hi
instance_exec(&lamb)
# => hi
为什么会这样呢? 请注意,此问题与lambda为什么会引发错误无关。 这是众所周知的。 问题是关于WHY instance_eval
将接收方的self
发送为参数。 不需要它,并且令人困惑。 而且AFAIK没有记录。
这会有所帮助,但不能解释为什么红宝石会这样做。 instance_eval
是将self
设置为接收者; 为什么还要通过将self
传递给过程来混淆事物?
来自文档
对于使用lambda或->()创建的proc,如果将错误数量的参数传递给具有多个参数的Proc,则会生成错误。 对于使用Proc.new或Kernel.proc创建的proc,多余的参数将被静默丢弃。
在您的情况下, lamb
和proc
使用一个参数调用
给instance_eval一个块时,obj也作为该块的唯一参数传入
instance_eval
是BasicObject
类的方法,可以在实例中调用。 因此,例如,给定的块将可以访问私有方法。
class Test
def call
secret_number + 100
end
private
def secret_number
42
end
end
test = Test.new
show_secret = -> (obj) { puts secret_number }
test.instance_eval(&show_secret) # print 42
没有实例,当前上下文的self
将作为参数传递。 我认为instance_eval
设计目的是为了在对象内调用它。
为了设置上下文,在代码执行时将变量self设置为obj,从而使代码可以访问obj的实例变量和私有方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.