どうもこんにちは。
Objectクラスのdupメソッドとcloneメソッドについて勉強したので、備忘録として残します。
dupメソッドとcloneメソッド
これらはどちらもオブジェクトのコピーを作成するためのメソッドです。
しかし、動作自体には微妙な違いがあります。実際、Ruby Goldの試験では違いを問う問題が出題されます。
ちなみに、Rubyにcopy
メソッドは存在しません。
dupメソッド
オブジェクトの浅いコピー(シャローコピー)を作成します。
主にオブジェクトの状態(インスタンス変数など)をコピーしますが、特定の属性(例えばフリーズ状態やシングルトンメソッドなど)はコピーされません。
cloneメソッド
dup
と同様にオブジェクトの浅いコピーを作成しますが、追加で以下の要素もコピーします。
- フリーズ状態(
frozen?
) - テインティング状態(
tainted?
)- テインティングについては、Ruby2.7以降では廃止されているようですので、ここでの解説は省きます
- シングルトンメソッドや特異メソッド
特徴 | dupメソッド | cloneメソッド |
---|---|---|
フリーズ状態のコピー | コピーされない | コピーされる |
テインティング状態のコピー | コピーされない | コピーされる |
シングルトンメソッドのコピー | コピーされない | コピーされる |
コンスタントのコピー | 対応していない(クラス定数など) | 対応している場合がある(主にシングルトンクラス) |
基本的な用途 | オブジェクトの単純な複製 | オブジェクトの完全な複製 |
違いについて解説
ここから、違いについての詳細を解説します。
1. フリーズ状態のコピー
dup
メソッドでは、元のオブジェクトがフリーズされていても、コピーされたオブジェクトはフリーズされていません。
一方、cloneメソッドでは、元のオブジェクトがフリーズされている場合、コピーされたオブジェクトもフリーズされています。
# dupの例
original = "Hello".freeze
copy = original.dup
puts original.frozen? # => true
puts copy.frozen? # => false
# cloneの例
original = "Hello".freeze
copy = original.clone
puts original.frozen? # => true
puts copy.frozen? # => true こっちはフリーズ状態もコピーされている!
2. シングルトンメソッドのコピー
シングルトンメソッドとは、特定のオブジェクトにのみ定義されたメソッドのことです。
dupメソッドでは、これらのメソッドはコピーされませんが、cloneメソッドではコピーされます。
# dupの例
original = "Hello"
def original.greet
"こんにちは"
end
copy = original.dup
puts original.greet # => こんにちは
puts copy.respond_to?(:greet) # => false
# cloneの例
original = "Hello"
def original.greet
"こんにちは"
end
copy = original.clone
puts original.greet # => こんにちは
puts copy.greet # => こんにちは
まとめ
どちらも浅いコピーを行うメソッドですが、複製を行える範囲が異なることを理解できたと思います。
Ruby Goldの試験で出てくるので、覚えておきましょう。