红宝石法阵#<<不更新哈希数组 [英] Ruby method Array#<< not updating the array in hash

查看:135
本文介绍了红宝石法阵#<<不更新哈希数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

按<一个启发href=\"http://stackoverflow.com/questions/2552363/how-can-i-marshal-a-hash-with-arrays\">http://stackoverflow.com/questions/2552363/how-can-i-marshal-a-hash-with-arrays我不知道有什么原因,阵列#&LT;&LT; 不会在以下code正常工作:

Inspired by http://stackoverflow.com/questions/2552363/how-can-i-marshal-a-hash-with-arrays I wonder what's the reason that Array#<< won't work properly in the following code:

h = Hash.new{Array.new}
#=> {}
h[0]
#=> []
h[0] << 'a'
#=> ["a"]
h[0]
#=> [] # why?!
h[0] += ['a']
#=> ["a"]
h[0]
#=> ["a"] # as expected

是否有与事实做&LT;&LT; 改变就地数组,而阵列#+ 创建一个新的实例?

Does it have to do with the fact that << changes the array in-place, while Array#+ creates a new instance?

推荐答案

如果您创建一个使用块形式Hash.new <α哈希 / code>,该块被执行每次试图访问实际上并不存在的元素时。所以,让我们只是看看会发生什么:

If you create a Hash using the block form of Hash.new, the block gets executed every time you try to access an element which doesn't actually exist. So, let's just look at what happens:

h = Hash.new { [] }
h[0] << 'a'

这被评价这里的第一件事,就是前pression

The first thing that gets evaluated here, is the expression

h[0]

当它被评估会发生什么?那么,该块被运行:

What happens when it gets evaluated? Well, the block gets run:

[]

这是不是很兴奋:块简单的创建一个空数组并返回它。它不会做别的。特别是,它不会改变 ^ h 以任何方式: ^ h 仍是空的。

That's not very exciting: the block simply creates an empty array and returns it. It doesn't do anything else. In particular, it doesn't change h in any way: h is still empty.

其次,消息&LT;&LT; 用一个参数'A'被发送到的结果 H [0] 这是块,这简直是一个空数组的结果是:

Next, the message << with one argument 'a' gets sent to the result of h[0] which is the result of the block, which is simply an empty array:

[] << 'a'

这是什么呢?它添加了元素'A'为空数组,但由于阵实际上并不能够分配到任何变量,它立即被垃圾回收和消失。

What does this do? It adds the element 'a' to an empty array, but since the array doesn't actually get assigned to any variable, it is immediately garbage collected and goes away.

现在,如果你评估 H [0] 又说:

Now, if you evaluate h[0] again:

h[0] # => []

^ h 还是的空的,因为从来都没有得到分配给它,因此关键 0 仍是不存在的,这意味着该块被运行的再次的,这意味着它的再次的返回一个空数组(但要注意,这是一个全新的,不同的的空数组现在)。

h is still empty, since nothing ever got assigned to it, therefore the key 0 is still non-existent, which means the block gets run again, which means it again returns an empty array (but note that it is a completely new, different empty array now).

h[0] += ['a']

在这里是什么情况?首先,操作者分配被脱糖到

What happens here? First, the operator assign gets desugared to

h[0] = h[0] + ['a']

现在,在 H [0] 上的右键的一侧被评估。它有什么回报?我们已经走到了这一点: H [0] 不存在,因此该块被运行,该块返回一个空数组。再次,这是一个全新的,的第三的空数组现在。这个空数组被发送的消息 + 通过参数 ['一'] ,这会导致它没有返回另一个的新数组是数组 ['一'] 。此数组然后被分配到 H [0]

Now, the h[0] on the right side gets evaluated. And what does it return? We already went over this: h[0] doesn't exist, therefore the block gets run, the block returns an empty array. Again, this is a completely new, third empty array now. This empty array gets sent the message + with the argument ['a'], which causes it to return yet another new array which is the array ['a']. This array then gets assigned to h[0].

最后,在这一点:

h[0] # => ['a']

现在你的最后的实际东西放在 H [0] 所以,很显然,你得到了你把什么

Now you have finally actually put something into h[0] so, obviously, you get out what you put in.

因此​​,要回答你大概过了,你为什么不出去,你放什么问题吗?您的没有的在第一时间把任何东西!

So, to answer the question you probably had, why don't you get out what you put in? You didn't put anything in in the first place!

如果你真的想的分配应用于块中的哈希,你必须这样做,以及分配给块内的哈希值:

If you actually want to assign to the hash inside the block, you have to, well assign to the hash inside the block:

h = Hash.new {|this_hash, nonexistent_key| this_hash[nonexistent_key] = [] }
h[0] << 'a'
h[0] # => ['a']

这其实很容易看到正在发生的事情在你的code例如,如果你看一下涉及到的对象的身份。然后,你可以看到,每次你打电话 H [0] ,你得到的不同的的数组。

这篇关于红宝石法阵#&LT;&LT;不更新哈希数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆