13

Ruby の dup メソッドと clone メソッドの違いは何ですか? dupは、との動作の違いについて説明していcloneます。しかし、いつ使用するdup必要があり、clone代わりにいつ使用する必要がありますか?

clone ではなく dup を使用した理由、またはその逆を使用した理由を説明する実際のプロジェクトの例は、この質問に理想的です。

または、2 つの異なる方法が存在する理由の説明が役立ちます。これは、Ruby の作成者からのステートメント、または Ruby に影響を与えた言語のdupやのようなメソッドの調査を参照することができます。clone

4

2 に答える 2

8

がオブジェクトcloneの状態をコピーするのは事実ですが、そうではありません。frozendup

o = Object.new
o.freeze

o.clone.frozen?
#=> true

o.dup.frozen?
#=> false

cloneオブジェクトのシングルトンメソッドもコピーしますが、コピーしdupません:

o = Object.new
def o.foo
  42
end

o.clone.respond_to?(:foo)
#=> true

o.dup.respond_to?(:foo)
#=> false

cloneこれは、 よりも「より深い」コピーを提供すると理解されることがあるという仮定に私を導きますdup。このトピックに関するいくつかの引用を次に示します。

ActiveRecord::Base#initialize_dupRails 3 からのコメント:

複製されたオブジェクトには ID が割り当てられておらず、新しいレコードとして扱われます。これはオブジェクトのアトリビュートのみをコピーし、関連付けはコピーしないため、「浅い」コピーであることに注意してください。「ディープ」コピーの範囲はアプリケーション固有であるため、アプリケーションの必要に応じて実装する必要があります。

Ruby のディープ コピーに関する記事:

言及する価値のある別の方法がありcloneます。このcloneメソッドは と同じことをdup行いますが、重要な違いが 1 つあります。オブジェクトは、ディープ コピーを実行できるメソッドでこのメソッドをオーバーライドすることが予想されます。

しかし、deep_dupRails 4 には次のようなものがあります。

複製可能なオブジェクトのディープ コピーを返します。複製できない場合は、 を返しますself

またActiveRecord::Core#dup#cloneRails 4 では:

clone— Ruby の clone メソッドと同じです。これは「浅い」コピーです。属性がコピーされないことに注意してください。[...] 属性ハッシュのコピーが必要な場合は、#dupメソッドを使用してください。

つまり、ここでもこの単語dupはディープ クローンを指すために使用されています。私が見る限り、いずれかの特定の副作用が必要な場合にcloneandを使用する必要があることを除いて、コミュニティにはコンセンサスがないようです。dup

最後に、私はdupRuby コードよりもはるかに頻繁に見かけますclone。私はcloneこれまで一度も使用したことがなく、明示的に必要になるまで使用しません。

于 2014-05-28T20:11:22.083 に答える
5

DUP と CLONE の両方を使用して、オブジェクトの浅いコピーを作成できます。どちらも obj のインスタンス変数をコピーします。しかし、それらの使用法を選択する必要があります。

これらの違いはほとんどありません

1) CLONE はオブジェクトの FROZEN 状態と TAINTED 状態の両方をコピーしますが、DUP はオブジェクトの TAINTED 状態のみをコピーします。

2) CLONE を使用すると、オブジェクトの任意のシングルトン メソッドをコピーできますが、DUP はこれをサポートしていません。

CLONE は内部状態を含むオブジェクトを複製するために使用され、DUP は通常、子孫オブジェクトのクラスを使用して新しいインスタンスを作成します。

ActiveRecord行を複製するためにDUPを使用しているときに苦い経験がありました.これは元のものを失うことになり、CLONEでも同じように機能しました.

私は混乱に身を包んでいたので、オープンソースの記事が広く開かれていることが明らかであることがわかりました

于 2012-08-01T04:17:46.967 に答える