捕获的块变量是什么?

时间:2012-10-04 13:24:45

标签: ruby

一个教程有这段代码:

h1 = ["a" => 111, "b" => 222]
h2 = ["b" => 333, "c" => 444]
h1.merge(h2) {|key, old, new| new}
# => ["a" => 111, "b" => 333, "c" => 444]
h1.merge(h2) {|key, old, new| old}
# => ["a" => 111, "b" => 222, "c" => 444]

我们与合并有冲突。两个数组中有两个重复键。 new正在捕获h2的{​​{1}}值,并输出它会强制它在合并中具有优先权。同样,"b"正在捕获old的{​​{1}}值,并强制它优先使用。

为什么我们似乎只抓取h1的值?变量不应该抓住整个数组吗?与"b"一起使用时,块变量是上下文相关的还是更改函数,而不是"b"?或者,当我们处理数组而不是简单的数字时,它们是否会改变函数?还是他们看到合并冲突,就像“我们必须抓住冲突点”?我想也许试图看看.merge中的内容会有所帮助,

.times

但它实际上让我更加困惑。为什么一个变量捕获密钥,而其他变量捕获两个不同的值?

3 个答案:

答案 0 :(得分:2)

它正在合并:在h1.merge(h2)中,'h1'是“旧”哈希,'h2'是“新”哈希。仅为具有两个哈希值的键调用该块。该块获得3个参数:每个键和每个哈希的相应值。块中的逻辑选择将哪一个放入该键的输出哈希中。只有一个哈希值的任何键直接进入输出而不通过块处理。

您可以通过运行

更好地了解正在发生的事情
 h1.merge(h2){|key,left,right| print "k=#{key} l=#{left} r=#{right} "}

来自Ruby-Doc.org说明:

  

返回一个包含other_hash和的内容的新哈希   hsh的内容。如果未指定块,则条目的值为   重复键将是other_hash的重键。否则值为   通过使用密钥调用块来确定每个重复的密钥,   它在hsh中的值及其在other_hash中的值。

因此,为了回答您的一个具体问题,是的,有条件地调用该块,仅用于冲突的密钥,而不像.each或.delete_if这样的方法,这些方法是为每个密钥调用的。

答案 1 :(得分:1)

我建议你研究一下块和块变量在ruby中是如何工作的,因为我认为这就是你绊倒的原因。

例如,此resource可能会有所帮助。

答案 2 :(得分:0)

来自merge的文档。以这种方式使用三个参数key, old, new

  • 如果key仅存在于其中一个哈希值中,那么该哈希值中的值将用于构建合并
  • 如果两个哈希中都存在key,则返回proc(block){|key, old, new| key }的返回值,在这种情况下为key,这是要插入哈希的键。

当两个哈希值之间存在关键冲突时,您可以执行其他操作,例如{|key, old, new| old - new }来调用计算。以下是合并文档中的一个示例:

h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
               #=> {"a"=>100, "b"=>54,  "c"=>300}