2012-05-01 42 views
7

我有这样一段代码:红宝石散列错误:未定义的方法[]

my_hash = {} 
first_key = 1 
second_key = 2 
third_key = 3 
my_hash[first_key][second_key][third_key] = 100 

和Ruby解释器给了我一个错误说:

undefined method `[]' for nil:NilClass (NoMethodError)

那么是否意味着我不能使用那样的哈希?或者你认为这个错误可能是因为别的东西?

+0

关于如何调试代码的提示:http://stackoverflow.com/q/3955688/38765 –

+0

艾伦,除非你认为你的问题没有完全解答,否则你应该接受其中一个答案。 (可能是texasbruce或者我的,因为我们告诉你一种实现你想要的方式,虽然我重复说它不一定是好风格。) –

回答

10

默认情况下,哈希不是嵌套的。由于my_hash[first_key]未被设置为任何值,因此它是nil。而nil不是散列,所以试图访问其中的一个元素失败。

所以:

my_hash = {} 
first_key = 1 
second_key = 2 
third_key = 3 

my_hash[first_key] # nil 
my_hash[first_key][second_key] 
# undefined method `[]' for nil:NilClass (NoMethodError) 

my_hash[first_key] = {} 
my_hash[first_key][second_key] # nil 

my_hash[first_key][second_key] = {} 

my_hash[first_key][second_key][third_key] = 100 
my_hash[first_key][second_key][third_key] # 100 
+0

你好,谢谢,但实际上我让我的散列是静态的('@@ my_hash' ),那么子哈希值也是静态的吗?所以如果我把这段代码放在一个循环中,sub_hashes将不会再被初始化? –

+5

@AllanJiang Ruby中没有“静态”的东西。 –

2

不能使用哈希像; my_hash[first_key]只是零,然后下一个索引操作失败。有可能创建一个散列对象,其行为方式与您要查找的相同 - 请参阅http://t-a-w.blogspot.co.uk/2006/07/autovivification-in-ruby.html - 但尚不清楚这是否是一种很好的风格。

+0

谢谢你的回答!我还有另外一个问题,请在另一个答案下看看我的评论。谢谢 –

7

你在使用散列的方式在Ruby中无效,因为在去嵌套散列(我想你是来自PHP?)之前,每个值都必须先分配给散列值,但是你可以使用鲜明的散列值:

my_hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)} 
first_key = 1 
second_key = 2 
third_key = 3 
my_hash[first_key][second_key][third_key] = 100 
p my_hash 

#output: {1=>{2=>{3=>100}}} 

这是您可能会感到舒服的方式。

+1

不错,不知道'default_proc'。 –

+0

@AndrewMarshall我从别人那里学到了:)我认为这个用法非常优雅。 – texasbruce

0

你可以像nil_overrides.rb的初始化像

class NilClass 

    def [] key 
    nil 
    end 

end 

,你将能够使用nil['xxx']