2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ruby 破壊の話①「=」のふるまい

Last updated at Posted at 2020-02-21

rubyの破壊するとかしないの話

はじめに

rubyを初めて書いてみて破壊するしないみたいな話題が出てきた際、いまいち想像できなかったので、ちょっと調べてみました。
調べていくうちに次第に興味がわいてきたので、一通り試したり調査して理解したことをまとめました。
全五回に分割してありますが、短くまとめてあるので、是非とも通して読んでいただきたいなと思います。

ruby 破壊の話シリーズ
ruby 破壊の話①「=」のふるまい
ruby 破壊の話②メソッド編
ruby 破壊の話③関数編
ruby 破壊の話④破壊的なメソッド編
ruby 破壊の話⑤dup編

全部読むと

  • 破壊とはどのように行われるか
  • =と破壊的メソッドの違い
  • 完全な複製の作り方

などが理解できると思います。

環境
$ ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
$ irb
irb(main):001:0>

"="

これをこれまで代入と呼んでいたけど、rubyだと代入とは違う気もする。

一番近いのは「エイリアス」かなと。

ちなみに"=="や”===”は全く関係ない。あくまで"="のふるまいの話をする。
突き詰めると"="のふるまいを理解してからrubyがかなり好きになったと思う。

rubyの=は代入ではない(と思う)。
これが他の言語と違っていて、最初は戸惑ったけど慣れるとむしろすごく良いシステムだった。

rubyの=は「左辺は右辺のオブジェクトを参照してね」という命令と理解している。idの代入じゃないかと言われるとまあ確かに代入かもしれない・・・

一回だけ使う場合

まずはわかりやすいmutableの例から。
mutableとかimutableの話はまた別の記事で書きます。

mutableの例

irb(main):001:0> a='aaa' #変数aが文字列aaaを指すように設定(文字列aaaはこの世界にたくさん存在する)
=> "aaa"
irb(main):002:0> a.__id__ #変数aのobject_id
=> 47197188120260
irb(main):003:0> a.__id__ #変数aはこの世界に一つしか存在しないので、何度確認しても変わらない
=> 47197188120260
irb(main):004:0> 'aaa'.__id__ #文字列aaaのobject_id
=> 47197187994020
irb(main):005:0> 'aaa'.__id__ #同じ文字列でも評価のたびに異なるobjectであることが
=> 47197187807940
irb(main):006:0> 'aaa'.__id__ #object_idを確認すればわかる
=> 47197187768200
irb(main):007:0> 'aaa'.__id__=='aaa'.__id__ #評価のたびに異なるからfalse
=> false
irb(main):008:0> a.__id__=='aaa'.__id__ #参照してねという命令であり、この'aaa'はさっき(001)の'aaa'とは異なるのでfalce
=> false

immutableの例

muttableとだいぶ異なることがわかる

irb(main):001:0> a=:aaa #変数aがシンボルaaaを指すように設定(シンボルaaaはこの世界に一つしか存在しない)
=> "aaa"
irb(main):002:0> a.__id__ #変数aのobject_id
=> 1162268
irb(main):003:0> a.__id__ #変数aはこの世界に一つしか存在しないので、何度確認しても変わらない
=> 1162268
irb(main):004:0> :aaa.__id__ #シンボルaaaのobject_idはaに割り当てられたidと同じ
=> 1162268
irb(main):005:0> :aaa.__id__ #同じシンボルなら常に同じidであることが
=> 1162268
irb(main):006:0> :aaa.__id__ #object_idを確認すればわかる
=> 1162268
irb(main):007:0> a.__id__==:aaa.__id__ #世界に一つの変数aとシンボルaaaの参照先を001でそろえたので
=> true
irb(main):008:0> a.__id__===:aaa.__id__ #これら二つはどこまでも同じ
=> true

複数回使う場合

mutableの例

irb(main):001:0> a='abc' #変数aが文字列abcを指すように設定
=> "abc"
irb(main):002:0> a.__id__ #変数aのid
=> 46923898737600
irb(main):003:0> a="abc" #一見意味のないコード
=> "abc"
irb(main):004:0> a.__id__ # 003で新たな参照先に変わったのでidも変わる
=> 46923898698140
irb(main):005:0> a="cba" # もちろん異なる文字列に設定すると
=> "cba"
irb(main):006:0> a.__id__ #idも変わる
=> 46923898682240
irb(main):007:0> a=a #左辺aの参照先を右辺aの参照先に設定する
=> "cba"
irb(main):008:0> a.__id__ #右辺aの参照先は006の値だから設定しなおしても変わらない
=> 46923898682240
irb(main):009:0> a=a+"x" #左辺aの参照先を右辺aにxをつなげたオブジェクトに設定する
=> "cbax"
irb(main):010:0> a.__id__ #右辺aにxをつなげたオブジェクトはaとは異なるオブジェクトなのでidも異なる
=> 46923898381420

immutableの例

こちらもかなり異なる

irb(main):001:0> a=:abc #変数aがシンボルabcを指すように設定
=> :abc
irb(main):002:0> a.__id__ #変数aのid
=> 1162268
irb(main):003:0> :abc.__id__ #シンボルabcのidと一致する
=> 1162268
irb(main):004:0> a=:abc #一見意味のないコード
=> :abc
irb(main):005:0> a.__id__ #immutableの場合は本当に意味が無い
=> 1162268
irb(main):006:0> a=:cba #aの参照先をシンボルcbaに変更
=> :cba
irb(main):007:0> a.__id__ #参照先が変わったのでidも変更
=> 1162588
irb(main):008:0> :cba.__id__ #参照先はシンボルcbaと一致
=> 1162588

ざっくり"="は参照先idを更新する命令だという理解で良いと思う。
逆に=が無ければidは変わらないし、値も変わらない。。。

わけではない。
実は=なしで値は変えられる。
続きは次の記事で。

まとめ

rubyにおける「=」の働きは、object_idを上書きすることである。

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?