Perlでは、デフォルトでリファレンス構造(たとえば、配列の配列やハッシュのハッシュ)のコピーは浅く行われます:リンクのみがコピーされ、ネストされた内容はコピーされません。歴史的に、これはしばしば予期しない効果を引き起こしました — 一つのコピー内の内部構造の変更が他のコピーに反映されます。解決策:専門のメソッドやモジュールを使用して深いクローンを作成し、独立したネストした要素を持つ独立した構造を作成します。
コードの例(Storableを使用):
use Storable 'dclone'; my $original = { a => [1, 2, { x => 10 }] }; my $copy = dclone($original); $copy->{a}[2]{x} = 20; print $original->{a}[2]{x}; # 10
主な特徴:
“=”演算子($copy = $ref)は深いコピーに機能しますか?
いいえ、“=”演算子はリンクそのもののみをコピーします。このような代入の後、$copyの変更は$refにも反映されます。
Data::Dumper関数を深いコピーに使用できますか?
Data::Dumperはデバッグと文字列へのシリアル化のためのツールであり、メモリ内のデータ構造を復元するためには設計されていません。逆変換にはevalが必要で、これは危険であり、安全性やパフォーマンスの理由から推奨されません。
dcloneは常にオブジェクト(Blessed reference)で正しく動作しますか?
Storable::dcloneはオブジェクトをクローンしますが、クラスがシリアル化メソッドをオーバーロードしたり、非標準オブジェクト(たとえば、ファイルディスクリプタや外部リソースへの強いリンク)を含んでいない場合に限ります。複雑なオブジェクトには、STORABLE_freezeとSTORABLE_thawメソッドを実装する必要があります。
配列の配列が=演算子で複製され、ネストされた構造の一部に変更が加えられると、すべてのコピーに同じ変更が表示されます。
利点:
欠点:
Storable::dcloneまたはClone::PPが使用され、すべてのネストされた構造が独立しています。
利点:
欠点: