RubyのObject#cloneがdeep copyしない理由は簡単。相互参照がある場合や、コピーできないものを内包していた場合の挙動をグローバルに(Object/Kernelで)定義するのが難しいから。
もっと利用側寄りの理由としては、deep copyされたくないケースも多いから。特に、ArrayやHashのように何でも入れられるコンテナオブジェクトが、dup/cloneで各要素をdup/cloneして回るべきかと言われると躊躇する。コネクションオブジェクトやソケット、ファイルハンドルもdupする?
一方、メンバの参照コピー(shallow copy)で足らない部分は、適宜自分のクラスのinitialize_copyメソッドで定義できる。たとえばメッセージダイジェストを計算するオブジェクトなら、内部ベクタなどについては”deep copy”する。でないと、クローンを操作したらコピー元の値や状態まで変わった、ということになってしまう。何をdeep copyすべきかというのは各オブジェクトが知っており、自分が固有に持つものについては自分が責任を持ってコピーする。
Perlは文字列や配列がオブジェクトでないので、文字列の配列などは単なる代入によって実質deep copyになる。その辺が感覚の違いを生むのだろう。
ちなみに、Rubyで手軽にdeep copyしたければMarshal.load(Marshal.dump(obj))
が定石。これはPerlのStorable::dclone(obj)
と等価。
I don’t think the title of your article matches the content lol. Just kidding, mainly because I had some doubts after reading the article.