【问题标题】:Ruby: Implicit Block Converted to ProcRuby:隐式块转换为 Proc
【发布时间】:2021-06-26 23:31:42
【问题描述】:

我的理解是隐式附加到方法的块必须被屈服;它不能被调用。所以我试图理解为什么会这样:

def execute_code
  proc.call
end

execute_code { "Why does this work?" } # => "Why does this work?"

将块附加到此代码成功执行。

有什么见解吗?我还没有找到任何文档暗示隐式块会自动转换为 proc 对象并分配给变量proc

Ruby 2.5.3

【问题讨论】:

    标签: ruby anonymous-function proc


    【解决方案1】:

    对于 Ruby 2.5.3,docs for Kernel#proc() 说:

    相当于 Proc.new。

    docs for Proc.new 说:

    创建一个新的Proc 对象,绑定到当前上下文。 Proc::new 只能在带有附加块的方法中调用而没有块,在这种情况下,该块将转换为 Proc 对象。

    这就是您的示例中发生的情况。您正在一个带有块的方法中调用proc,并且该块正在转换为Proc.

    但是,此行为在以后的版本中发生了变化。如果你在 Ruby 2.7,1 中尝试,你会收到这样的警告(尽管它仍然可以工作):

    proc.rb:2: warning: Capturing the given block using Kernel#proc is deprecated; use `&block` instead
    

    在 Ruby 3 中,它根本不起作用(事实上,它的行为与您预期的一样):

    proc.rb:2:in `proc': tried to create Proc object without a block (ArgumentError)
        from proc.rb:2:in `execute_code'
        from proc.rb:5:in `<main>'
    

    docs for 3.0.0 没有改变。这看起来像是文档中的一个错误(它一直是fixed in master)。看起来这首先在2014 的问题跟踪器中提出,然后在2019 中提出。

    【讨论】:

    • 显然,这从来都不是真正的意图。 Kernel#proc 只是从堆栈中取出最顶部的块,假设它是传递给自身的块。使它成为“官方”的文件后来出现了。至少,这是我听到的故事。基本上,一个编程错误被提升为一个功能,后来被认为是一个错误,因此被删除但留在文档中,从而使文档出现错误:-D
    猜你喜欢
    • 2011-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多