はじめてのRuby!dupメソッドの使い方をやさしく解説

こんにちは!エンジニアのタナカゴダイです。

rubyのオブジェクトをコピーして、コピー先のオブジェクトの中身を変更したとき、「コピー元のオブジェクトの中身も変わってしまった…」というような経験はありませんか?

そのような問題を解決する方法として、オブジェクトのコピーを作成するdupメソッドがあります。


【基礎】dupメソッドとは何か?
【基礎】dupメソッドの使い方
【発展】dupメソッドの類似メソッドであるcloneメソッドとは?
【発展】dupメソッドとcloneメソッドの違い

などのdupメソッドに関連する基本から応用的な内容についても解説していきます。

dupメソッドとは

dupメソッドとは、オブジェクトのコピーを作成するメソッドです。

dupメソッドはオブジェクトのインスタンス変数をコピーした後に、Objectクラスのinitialize_copyメソッドを呼び出します。

そして、Objectクラスが持つインスタンスメソッドなので、オブジェクトに続けてメソッドを使用することができます。

dupメソッドの基本的な書き方を以下に記載します。

上記サンプルプログラムでは、original_objectの内容をdupメソッドでcopied_objectにコピーを作成しています。

出力結果を確認すると、original_objectの値がcopied_objectにコピーされていることがわかります。

dupメソッドの基本的な使い方

ここでは、dupメソッドは「どのようにオブジェクトをコピーしているか」を、サンプルプログラムを用いて詳しく解説していきます。

初めに結論から述べると、dupメソッドはオブジェクトの参照値をコピーして新しくオブジェクトを作成しています。

つまり、dupメソッドを使用してオブジェクトをコピーすると、オブジェクトが持つidが新しく生成されるのです。

この挙動はdupメソッドを使用した場合と、=を使用した場合のobject_idの変化を確認しながら理解するといいでしょう。

以下のサンプルプログラムでは、aに配列[{:a=>1}, {:b=>2}, {:c=>3}]を代入し、そのaをbに代入、さらにbをdupメソッドでコピーしています。

この時のa, b, cそれぞれのobject_idを①で確認します。

さらに、b[0]の値を変更し、a, b, cそれぞれの値の確認を②で行っています。

上記サンプルプログラムの出力結果は以下の通りです。

①の結果では、aのobject_idとbのobject_idが等しくなっています。

=を使用した場合は、bにaというオブジェクトを代入する、という挙動になるためaとbのobject_idが等しくなります。

対して、cのobject_idはdupメソッドを使用したことにより、新しいobject_idになっていることがわかります。

そして、object_idが異なるということは②の結果に影響を与えます。

②では、b[0]の値を変更して、a, b, cそれぞれの値を出力していますが、①で分かった通りaとbは同じオブジェクトを参照しているため、b[0]の値を変更するとaの出力結果も変わってきます。

cは、a, bと異なるオブジェクトを参照しているため、b[0]の値を変更してもcの値の出力結果には影響が出ないというわけです。

このようにして、dupメソッドは値をコピーして新たにオブジェクトを作成するメソッドなのです。

dupメソッドとcloneメソッドの違いとは

dupメソッドに類似しているメソッドとして、cloneメソッドがあります。

cloneメソッドとは、dupメソッドと同様にオブジェクトをコピーして作成するメソッドです。

書き方はdupメソッドと変わりなく、オブジェクトに続けてcloneメソッドを使用します。

では、dupメソッドとcloneメソッドでは何が違うのでしょうか。

どちらもオブジェクトをコピーするメソッドですが、以下の点において、2つのメソッドに差異が生じます。


・cloneメソッドは凍結状態/汚染状態/信頼状態/特異メソッドまでコピー
・dupメソッドは汚染状態/信頼状態をコピーし、凍結状態/特異メソッドはコピーしない

以下の表で、dupメソッドとcloneメソッドの差異についてまとめました。

メソッド凍結状態汚染状態信頼状態
特異メソッド
dupメソッドコピーしないコピーするコピーするコピーしない
cloneメソッドコピーするコピーするコピーするコピーする

それでは実際にdupメソッドとcloneメソッドの違いを確認してみましょう。

凍結状態

凍結状態とは、オブジェクトが変更可能かどうかを示す状態のことです。

Objectクラスがもつfreezeメソッドで凍結状態に変更し、frozen?メソッドで凍結状態かどうかを確認することができます。

dupメソッドとcloneメソッドを使用した際のオブジェクトの凍結状態について、実際のサンプルプログラムで確認しましょう。

出力結果より、dupメソッドは凍結状態をコピーせず、cloneメソッドは凍結状態をコピーすることがわかります。

汚染状態

汚染状態とは、オブジェクトが汚染されているかどうかを示す状態のことです。

Objectクラスがもつtaintメソッドで汚染状態に変更し、untaintメソッドで汚染状態を解除できます。

また、tainted?メソッドで汚染状態かどうかを確認することができます。

dupメソッドとcloneメソッドを使用した際のオブジェクトの汚染状態について、実際のサンプルプログラムで確認しましょう。

出力結果より、dupメソッドとcloneメソッドはどちらも汚染状態をコピーすることがわかります。

信頼状態

信頼状態とは、オブジェクトが信頼されているかどうかを示す状態のことです。

Objectクラスがもつtrustメソッドで信頼状態に変更し、untrustメソッドで信頼されていない状態に変更します。

また、untrusted?メソッドで信頼状態かどうかを確認することができます。

dupメソッドとcloneメソッドを使用した際のオブジェクトの信頼状態について、実際のサンプルプログラムで確認しましょう。

出力結果より、dupメソッドとcloneメソッドはどちらも信頼状態をコピーすることがわかります。

特異メソッド

最後に特異メソッドについて確認します。

特異メソッドとは、簡潔に説明すると対象のオブジェクトが固有で持つメソッドのことです。

以下は、aというオブジェクトにsingular_methodという特異メソッドを定義し、この特異メソッドsingular_methodが、dupメソッドとcloneメソッドでコピーされるか否かを確認するサンプルプログラムです。

出力結果より、dupメソッドはNoMethodErrorが出ているため特異メソッドsingular_methodまではコピーしていないことがわかり、cloneメソッドは特異メソッドsingular_methodまでコピーしていることがわかります。

まとめ

この記事では、dupメソッドの使い方をサンプルプログラムを用いて解説しました。

dupメソッドは、オブジェクトのコピーを作成するメソッドです。

また、dupメソッド以外のオブジェクトのコピーを作成するcloneメソッドについても違いとともに解説しました。

ぜひこの機会にdupメソッド/cloneメソッドをマスターしてください!

Rubyカリキュラム無料公開中!

この記事はRuby入門完全攻略ガイド【基礎学習/アプリ開発/仕事獲得】の一部になります。このカリキュラムは、プログラミング入門者が、基礎学習からアプリ開発、さらには仕事獲得まで体系的に学べる内容となっています。

Ruby学習に必要な情報を一つにまとめていますので効率よくRubyを学ぶことが出来ます。この機会に是非活用していただければと思います。

【Ruby入門ガイド】アプリ開発で知っておくべき知識を総ざらい
更新日 : 2018年11月23日

Rubyを最短で習得したい方へ

近年では様々なWEBサービスが流通するようになりました。

WEBサービスの普及が進むにつれて、それらを素早く開発するのに長けたRubyの人気は今後さらに増し、Rubyエンジニアの需要も自ずと増えることは間違いなしでしょう。

元々ITリテラシーの高い方や他言語を習得している方であれば、独学でRubyを習得することが可能です。

ただし、プログラミング学習をしている方の多くは

「自分に合った教材が見つけられずに挫折してしまった」
「勉強のための勉強になってしまい、ゴールが見えない」
「情報が少なくどう調べればいいかわからない」
「エラーを解決するのに何日もかかってしまう」

このような悩みを抱えたまま挫折してしまうのが現実となっています。

  • もう挫折したくない
  • 本業と両立しながら、好きな時間で自分のペースで勉強を続けていきたい
  • 自分だけのカリキュラムで効率的に勉強したい
  • WEBアプリケーション開発までしっかりサポートして欲しい
そんな方はお気軽に侍エンジニア塾までご相談ください。

お一人お一人に専属のインストラクターがつくので、初心者の方がつまづきがちな、「CookPad」、「Wantedly」、「食べログ」のようなWEBアプリケーション開発方法もスムーズに学習することできます。

実際にオリジナルWEBアプリを開発し、成果物として認められて仕事獲得に成功した塾生は数多くいます。

このように、オリジナルアプリ開発から仕事獲得まで徹底的にサポートすることでプログラミング初心者の方でも安心して基礎学習に取り組むことができます。

まずは『無料体験レッスン』で、弊社のコンサルタントと一緒にあなた専用の学習方法やカリキュラムを考えてみませんか?

Rubyならではの学習方法や、現役フリーランスRubyエンジニアから貴重なアドバイスを受けることができます。

詳しくは下の画像から弊社サービス内容をご確認ください。

ruby_a2
LINEで送る
Pocket

書いた人

侍テック編集部

侍テック編集部

おすすめコンテンツ

あなたにぴったりなプログラミング学習プランを無料で診断!

プログラミング学習の効率を劇的に上げる学習メソッドを解説