2017-10-23 10 views
-1

(1.9.3)理由コードが配列値を変更しない:ルビーハッシュ可変性

arr = ['a', 'b', 'c'] 
arr.each do |e| 
    e = 'new string' 
end 

このコード項目B変化ハッシュを行いながら:

hashh = { 
    'item-a' => 1, 
    'item-b' => [ 
    {'id'=>'a','name'=>'name-a'}, 
    {'id'=>'b', 'name'=>'name-b'} 
    ] 
} 

hashh['item-b'].each do |e| 
    e['name'] = 'new-name' 
end 

私はは私はハッシュを変更することができない理由により、値を変更するには、アレイ上マップを使用することができることを知っているが、ではない配列の値は?

+1

[Array#each vs. Array#map](https://stackoverflow.com/questions/5254128/arrayeach-vs-arraymap)の可能な複製 – anothermh

+3

'Array#each'では、値を変更することができます。それぞれ{| e | e.replace '新しい文字列'} '。 – mudasobwa

答えて

2

最初のケースは、ローカル変数の割り当てがあります

arr.each do |e| 
    e = 'new string' 
end 

さらに第二の実際の方法であるHash#[]=を使用しているが。 hash[:key] = "val"hash.send(:[]=, :key, "val")の構文砂糖であり、その方法の中ではハッシュの実際の更新はCコードを介して行われます。 Rubyで

+0

私は「synactic sugar」には一種の意見がありません。その意味で、 'foo.bar(true)'は 'foo.send(:bar、true)'の構文的な砂糖ですが、この質問には関係ありません。ポイントは '[] ='がメソッドであり、変数の代入はメソッドではありません。 – Max

+0

@Maxのフェアポイント、それは 'hash = [:foo、" bar ")'(それがパブリックメソッドであることを忘れてしまった) –

2

(1.9.3)なぜ、このコードは、配列の値を変更しません:

arr = ['a', 'b', 'c'] 
arr.each do |e| 
    e = 'new string' 
end 

このコードは、配列の値を使って何をすることはありません。なぜそれが変わるだろうか?ローカル変数eに文字列を代入するだけで、スコープからすぐに外れるので、全体が操作なしになります。

このコードアイテムB変化ハッシュを行いながら:

hashh = { 
    'item-a' => 1, 
    'item-b' => [ 
    {'id'=>'a','name'=>'name-a'}, 
    {'id'=>'b', 'name'=>'name-b'} 
    ] 
} 

hashh['item-b'].each do |e| 
    e['name'] = 'new-name' 
end 
Hash#[]=

ハッシュを変異させる方法であるが。値(ハッシュ)を変更するメソッドを呼び出すので、値が変更されます。

私は値が

mapの値を変更しない変更するには、アレイ上マップを使用することができることを知っています。 新しい配列を返します。 (まあ、明らかに、あなたmapの値を変更することができますが、それはそれがために設計されたものではありませんし、あなたがそれを行うべきではありません。)

は私が変更することができない理由により、ハッシュはではない配列の値ですか?

eachここでは何もしません。 2番目のケースでは、値を変更するメソッドを呼び出します。つまり、値が変更されます。最初のケースでは、は値を変更するメソッドを呼び出しません。実際には、はすべてにはコールしません。 Ergo、値は変更されません。