Ruby lambda的proc和’instance_eval’
当我将lambda传递给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抛出错误的原因。 这很好理解。 问题是关于为什么instance_eval
将接收者的self
作为参数发送。 它不是必需的,而且令人困惑。 AFAIK没有记录。
这有帮助,但没有解释为什么ruby会这样做。 instance_eval
是将self
设置为接收者; 为什么通过将self
传递给proc来混淆事物呢?
来自文档
对于使用lambda或 – >()创建的proc,如果将错误数量的参数传递给具有多个参数的Proc,则会生成错误。 对于使用Proc.new或Kernel.proc创建的proc,将以静默方式丢弃其他参数。
在你的情况下, lamb
和proc
用一个参数调用
来自instance_eval的文档
当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
设计更多是为了在对象中调用它。
来自instance_eval的文档
为了设置上下文,在代码执行时将变量self设置为obj,使代码可以访问obj的实例变量和私有方法。