Ruby の配列を別の変数に代入した際の挙動

Ruby のような言語を使っていると値渡しと参照渡しなどという概念もあまり意識しませんが、配列の代入は面白い挙動をするので備忘録として残しておきます。確認は Ruby 1.9.2 p290 を使い Max OS SnowLeopard で行いました。

まず String 型を別の変数に代入した際の挙動を確認。

str = "test"
str_copy = str
str_copy += "test"

この時 str には "test" が str_copy には "testtest" が代入されています。

一方で Array の場合。

ary = []
ary_copy = ary
ary_copy << 1

この場合 array_copy が [1] になるのは当然ですが、元になった ary の方も [1] になります。いわゆる浅いコピー(参照だけを渡すコピー)ですね。

参考までに、値渡しのような深いコピーを行いたい場合は Marshal を使います。

ary = []
ary_copy = Marshal.load(Marshal.dump(ary))
ary_copy << 1

この場合 ary の値は [] のまま更新されず ary_copy が [1] になります。Marshal クラスが何をしているかについては、リファレンスを参照してください。

http://www.ruby-lang.org/ja/old-man/html/Marshal.html