简体   繁体   English

Ruby:隐式块转换为 Proc

[英]Ruby: Implicit Block Converted to Proc

My understanding is that a block implicitly attached to a method must be yielded;我的理解是必须产生隐式附加到方法的块; it cannot be called.它不能被调用。 So I'm trying to understand why this works:所以我试图理解为什么会这样:

def execute_code
  proc.call
end

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

Attaching a block to this code executes successfully.将块附加到此代码会成功执行。

Any insight?有什么见解吗? I haven't found any documentation hinting that an implicit block is automatically converted to a proc object and assigned to the variable proc .我没有找到任何文档暗示隐式块会自动转换为 proc object 并分配给变量proc

Ruby 2.5.3 Ruby 2.5.3

For Ruby 2.5.3, the docs for Kernel#proc() say:对于 Ruby 2.5.3,Kernel#proc()的文档说:

Equivalent to Proc.new.相当于 Proc.new。

and the docs for Proc.new say:Proc.new的文档说:

Creates a new Proc object, bound to the current context.创建一个新的Proc object,绑定到当前上下文。 Proc::new may be called without a block only within a method with an attached block, in which case that block is converted to the Proc object. Proc::new只能在带有附加块的方法中调用而没有块,在这种情况下,该块将转换为Proc object。

which is what is happening in your example.这就是您的示例中发生的情况。 You are calling proc in a method with a block, and the block is being converted to a Proc.您正在使用块的方法中调用proc ,并且该块正在转换为Proc.

However this behaviour changes in later versions.但是,此行为在以后的版本中发生了变化。 If you try in Ruby 2.7,1 you will get a warning like this (although it will still work):如果您在 Ruby 2.7,1 中尝试,您将收到这样的警告(尽管它仍然有效):

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

In Ruby 3, it won't work at all (and in fact behaves as you seem to expect):在 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>'

The docs for 3.0.0 are unchanged though.不过3.0.0 的文档没有改变。 This looks like a bug in the docs (it has been fixed in master ).这看起来像是文档中的错误(已在 master 中修复)。 It looks like this was first raised in the issue tracker in 2014 and then later in 2019 .看起来这首先在2014 年的问题跟踪器中提出,然后在2019 年晚些时候提出。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM