2012-10-11 111 views

回答

7

當您創建這樣的哈希:

h = Hash.new([])  

這意味着,每當散列與尚未定義的鍵,它會返回訪問:

[] 

現在當你這樣做:

h[:key1] << "Ruby" 

h[:key1]返回[],到"Ruby"被推送,導致["Ruby"]作爲輸出,因爲這是返回的最後一個對象。當使用未定義的鍵訪問'h'時,它也被設置爲返回的默認值。 因此,當你這樣做:

h[:key1] or h[:key2] or h[:whatever] 

你會得到

"Ruby" 

作爲輸出。 希望這有助於。

+0

真的很好的答案!謝謝:-) – changelog

+0

沒問題的人!你也幫助我學習...我必須閱讀文檔才能找出發生的事情。 – mkz

2

這種結構Hash.new([])返回默認值,但該值未初始化的哈希值。假設默認值是散列的一部分,您正在嘗試使用散列。

你需要的是建設,這將在初始化一些關鍵的哈希:

hash = Hash.new { |h,k| h[k] = [] } 

hash[:key1] << "Ruby" 

hash #=> {:key1=>["Ruby"]} 
+0

這是關於Ruby的那些事情之一,我覺得它應該工作。感謝你的回答。當我被允許時,我會在5分鐘內接受它! – changelog

2

看Hash.new

new → new_hash 
new(obj) → new_hash 
new {|hash, key| block } → new_hash 

的文檔,如果這個哈希隨後通過一鍵訪問的不對應於散列條目,返回的值取決於用於創建散列的新樣式。

  1. 在第一種形式中,訪問返回nil。
  2. 如果指定了obj,則此單個對象將用於所有默認值。
  3. 如果指定了一個塊,將使用散列對象和鍵調用它,並返回默認值。如果需要,塊的責任是將值存儲在哈希中。

irb(main):015:0> h[:abc] # ["Ruby"] 

所以["Ruby"]返回默認值,而不是零,如果關鍵是沒有找到。

+0

我剛剛在腦海裏有一個燈泡的時刻。這實際上解釋了我認爲這是錯誤的。謝謝! – changelog

2

你實際上沒有設置值爲h[:keys] << "Ruby"。您只需爲未找到的鍵的返回默認數組添加一個值。所以沒有創建密鑰。

如果你寫這篇文章,它會好起來的:

h = Hash.new([]) 
h[:keys1] = [] 
h[:keys1] << "Ruby" 
+0

看,這很奇怪,因爲當我評估h [:key1]時,它會返回我期望的結果。 – changelog

+0

這是默認值,它將在任何缺少的密鑰上返回相同的數組。 – Matzi

+0

該死的!現在明白了。 – changelog

1

我不得不承認這個我絆倒了太多,當我讀了你的問題。我看了一下docs,但它變得清晰。

如果指定OBJ,這個單一的對象將被用於所有默認值

所以你實際上在做什麼是修改這個單一的數組對象,用於默認值,而不分配給鍵!

檢查出來:

h = Hash.new([]) 

h[:x] << 'x' 
# => ['x'] 

h 
# => {} 

h[:y] 
# => ['x'] # CRAZY TIMES 

所以,你需要做的分配不知何故 - h[:x] += ['x']可能是要走的路。

+0

你的回答讓我大笑!我是否認爲這不是明確的行爲? – changelog

+0

哈哈很高興聽到它。我會說這很清楚(因爲一旦你閱讀了文檔,這是相當明顯的),但也許不直觀(因爲你需要閱讀文檔來解決它!)。 –