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,将以静默方式丢弃其他参数。

在你的情况下, lambproc用一个参数调用

来自instance_eval的文档

当instance_eval被赋予一个块时,obj也作为块的唯一参数传入

instance_evalBasicObject类的方法,可以在实例中调用。 因此,给定块可以访问私有方法。

 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的实例变量和私有方法。