有人可以解释 Ruby 在块中使用管道字符吗?

Posted

技术标签:

【中文标题】有人可以解释 Ruby 在块中使用管道字符吗?【英文标题】:Can someone explain Ruby's use of pipe characters in a block? 【发布时间】:2011-05-13 12:59:30 【问题描述】:

有人可以向我解释一下 Ruby 在块中使用竖线字符吗?我知道它包含一个变量名称,它将在迭代时分配数据。但这叫什么?管道内可以有多个变量吗?还有什么我应该知道的吗?有没有关于它的更多信息的好链接?

例如:

25.times  | i | puts i 

【问题讨论】:

相关问题:***.com/questions/665576/… 【参考方案1】:

大括号定义了一个匿名函数,称为块。管道之间的标记是这个块的参数。所需的参数数量取决于块的使用方式。每次评估块时,需要该块的方法将根据调用它的对象传递一个值。

和定义方法一样,只是不存储在接受块的方法之外。

例如:

def my_print(i) 
  puts i
end

执行时会做同样的事情:

|i| puts i

唯一的区别是块是动态定义的而不是存储的。

示例 2: 以下语句是等价的

25.times &method(:my_print)

25.times |i| puts i

我们使用匿名块,因为作为块传递的大多数函数通常特定于您的情况,不值得为重用而定义。

那么当一个方法接受一个块时会发生什么?这取决于方法。接受块的方法将通过以明确定义的方式从其调用对象传递值来调用它。返回的内容取决于需要该块的方法。

例如:在25.times |i| puts i 中,.times 为 0 和调用者的值之间的每个值调用一次块,将值作为临时变量 i 传递到块中。 Times 返回调用对象的值。在本例中为 25。

让我们看看接受带有两个参数的块的方法。

:key1 => "value1", :key2 => "value2".each |key,value| 
     puts "This key is: #key. Its value is #value"

在这种情况下,每个键/值对都调用块,将键作为第一个参数,将值作为第二个参数。

【讨论】:

&my_print 语法无效,你的意思是 &method(:my_print) 你说得对。我没有时间测试那个例子,我知道 & 用于将变量的值视为 Proc。我只是忘记了方法不包含值。我已经更新了这个例子。感谢您指出这一点。 感谢您为我们这些来自 Java 的人解释了这样一个奇怪的概念。【参考方案2】:

管道指定由调用您的块的函数填充值的参数。它们可以有零个或多个,您应该使用多少个取决于您调用的方法。

例如,each_with_index 使用两个变量并将元素放在其中一个中,将索引放在另一个中。

here is a good description of how blocks and iterators work

【讨论】:

【参考方案3】:

块参数遵循与方法参数相同的所有约定(至少从 1.9 开始):您可以定义可选参数、可变长度参数列表、默认值等。这是pretty decent summary。

需要注意的一些事情:因为块在定义它的范围内看到变量,如果你传入一个与现有变量同名的参数,它将“隐藏”它 - 你的块将看到传递的在值和原始变量将保持不变。

i = 10
25.times  | i | puts i 
puts i #=> prints '10'

最后会打印“10”。因为有时即使你没有传入一个值(即你想确保你不会意外地从周围范围中破坏一个变量),这也是可取的行为,你可以在参数列表后的分号后指定块局部变量名称:

x = 'foo'
25.times  | i ; x | puts i; x = 'bar' 
puts x #=> prints 'foo'

这里,'x' 是块本地的,即使没有传入任何值。

【讨论】:

以上是关于有人可以解释 Ruby 在块中使用管道字符吗?的主要内容,如果未能解决你的问题,请参考以下文章

有人可以解释一下程序中以下两行的含义来实现管道吗?

如何在块外快速创建指向自身的弱指针

更好的 ruby​​ markdown 解释器?

在 Ruby 块中使用“返回”

printf - 奇怪的混杂结果。有人可以解释一下吗?

有人可以解释为啥我的最后一个 else 语句不会运行吗?