2012-10-04 79 views
0

一个教程有这个代码块:什么是块变量捕获?

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"b"的值,并输出它强制它在合并中优先。同样,old正在捕获h1"b"的值,并强制它优先。

为什么我们似乎只抓取"b"的值?这些变量不应该抓住整个数组吗?与.merge(而非.times)相反,块变量是否与上下文相关并更改了功能?或者当我们处理数组而不是简单的数字时,他们改变了函数?还是他们看到合并冲突,就像“我们必须捕捉到冲突点”?我想,也许想看看在key会有所帮助,

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

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

+0

我是很新的红宝石(和爱它),这似乎是在它需要的键一个接一个,如果有重复它采用了第二珍藏价值的第一种情况下。在第二种情况下,它会执行相同的操作,但会采用第一个集合(旧)的值。什么似乎混淆你的是,h1.merge()不修改H1,它返回一个新的对象。红宝石是真棒:)尽请注意,我不是100%肯定,如此评论,并希望有人能答对更好(或批准这个答案,让我开心:d) – 2012-10-04 13:27:32

回答

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内容和北方的 内容的新的哈希。如果未指定块,则 重复键的条目的值将为other_hash的值。否则,每个复制密钥的值为 通过使用密钥 在hsh中的值以及在other_hash中的值调用块来确定。

所以要回答你的一个具体问题,是的,该块被称为有条件的,只用于冲突的键,不像像每个键调用的.each或.delete_if之类的方法。

+0

好吧!好的,这实际上很明显。我认为,我的大部分困惑的是从思想来阻止在这里工作以同样的方式,因为他们对其他方法做;我现在看到他们没有。感谢您的回答!我现在将更多地关注块变量。 :) – Aujury

0

从文档merge。这三个参数key, old, new以这种方式使用:

  • 如果key仅存的哈希值,然后从该散列值被用来构建合并
  • 如果存在于两个哈希key然后返回值的一个从proc(块){|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} 
1

我劝你学习块和块变量如何红宝石工作,因为我认为这是什么绊倒你。

例如,这resource也许能派上用场。

+0

我认为你是对的!我想我只是没有足够的词汇(“块”)正确问及之前研究它。谢谢!! – Aujury