Ruby lambda 的过程和“instance_eval”

2024-06-23

当我将 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 sends self接收器的参数作为参数。它是不需要的,并且令人困惑。而且据我所知没有记录。

This https://www.saturnflyer.com/blog/the-difference-between-instanceeval-and-instanceexec有帮助,但没有解释为什么 ruby​​ 会这样做。整个要点instance_eval是设置self至接收者;为什么还要通过来混淆事情self到过程?


来自文档

对于使用 lambda 或 ->() 创建的过程,如果 错误数量的参数被传递给具有多个的 Proc 参数。对于使用 Proc.new 或 Kernel.proc 创建的过程,额外 参数被默默地丢弃。

在你的情况下lamb and proc用一个参数调用

来自instance_eval的文档 https://ruby-doc.org/core-2.5.1/BasicObject.html#method-i-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的文档 https://ruby-doc.org/core-2.5.1/BasicObject.html#method-i-instance_eval

为了设置上下文,变量 self 被设置为 obj,而 代码正在执行,使代码可以访问 obj 的实例变量 和私有方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Ruby lambda 的过程和“instance_eval” 的相关文章

随机推荐