質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

1090閲覧

Objectのコピーについて

Naggy

総合スコア32

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2017/02/03 19:00

###質問内容
http://qiita.com/sue738/items/92228f0ae0518bf0a693
によると、(インスタンスを参照にした変数)を参照した変数の挙動について、
b = a 、 b = a.dup, b = a.Marshal.load(Marhsal.dupm(a))
とやった場合ではその後に変数の参照先を変えた場合の挙動が変わるとありました。
b = a と他の2つは確かに異なるのですが、後者の2つの挙動は同じものでした。
URLの記事の説明と挙動が異なってしまっているのはなぜでしょうか。
dupが浅いコピーを行うのであれば、aとbの値は同じになると予想していたのですが、、

以下に私の試した内容を記載します。

###該当のソースコード

class TT attr_accessor :name def initialize(name) @name = name end end a = TT.new("taro") b = a.dup b.name = "jiro" p a.name p b.name c = Marshal.load(Marshal.dump(a)) c.name = "saburo" p a.name p c.name

出力結果

"taro"#これが"jiro"になると予想していました。 "jiro" #この2つは予想通りでした。 "taro" "saburo"

###使用している環境

ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin15]

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

やりたいことは多分こうです。

Ruby

1class TT 2 attr_accessor :name 3 def initialize(name) 4 @name = name 5 end 6end 7 8a = TT.new("taro") 9b = a.dup 10b.name.replace "jiro" 11p a.name 12p b.name 13 14a = TT.new("taro") 15c = Marshal.load(Marshal.dump(a)) 16c.name.replace "saburo" 17p a.name 18p c.name

b.name = "jiro"というのは、bオブジェクトの@nameへの新規代入なので、オブジェクトaには影響を与えません。replaceだと、abで共有しているStringオブジェクトを書き換えるので、aにも影響します。

投稿2017/02/04 03:00

otn

総合スコア84498

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Naggy

2017/02/04 08:07

なるほど、、ありがとうございます。 ということは元記事で b = a.dup, b = a.Marshal.load(Marhsal.dupm(a)) とでは挙動が違い、浅いコピーと深いコピーであるという説明は正しいのでしょうか。。
otn

2017/02/04 08:26

正しいです。
Naggy

2017/02/04 10:16

なるほど、、ちょっと複雑ですが、浅いコピーはオブジェクトの変数は同じオブジェクトを参照にしている状態でコピーし、 深いコピーは、オブジェクトの変数は別のオブジェクト(でも値は同じ)を参照にした状態でコピーするってことですね。 replaceを使うと値自体のオブジェクトの参照を変え、b.name = ""だとそのオブジェクトの変数の参照先のみを変える。 ありがとうございます。
guest

0

b.name = "jiro"では、"jiro"という新しいオブジェクトを代入しているので、元のオブジェクトが入ったままのa.nameには影響しません。

b.name << '!'のように、Stringオブジェクトを破壊的に変更すれば、aも変化します。

投稿2017/02/03 23:50

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問