こんにちは。Tomoyuki(@tomoyuki65)です。
「ミュータブル」と「イミュータブル」という言葉を聞いたことはありますか?
Rubyでは、この二つを意識してプログラミングをしていないと、時に不具合を招いてしまう危険があるんです。
この記事では、そんなRubyのミュータブルとイミュータブルについて解説します。
ミュータブルとイミュータブルとは?
ミュータブルとは「変更可能な」という意味で、反対にイミュータブルとは「変更できない」という意味になります。
ミュータブルなオブジェクトは破壊的な変更が適用できるため、場合によっては本来変わってほしくない値まで一緒に変わってしまう恐れがあります。
ミュータブルなオブジェクト例
Rubyのミュータブルなオブジェクトの例としては文字列(Stringクラス)が挙げられます。
例として以下のプログラムを実行してみて下さい。
# 初期値を「japan」とする配列を作成
country = Array.new(3, 'japan')
# 配列の要素を変数に格納
s = country[0]
# 変数sに破壊的な変更を加える
s.upcase!
# 配列を表示
p country
実行結果の通り、変数「s」に破壊的な変更を加えたのにも関わらず、配列の要素も変更されてしまいましたね。
このように、ミュータブルなオブジェクトであることを意識していないと、予期せぬ不具合を招いてしまうので注意しましょう。
配列の初期値を設定する場合の注意点
上記の例の通り、配列の初期値を引数で指定した場合、配列の一つ目の要素だけでなく、全ての要素が”JAPAN”に変更されてしまいました。
これは、配列の全要素が同じ文字列オブジェクトを参照しているために発生します。
この問題を回避するためには、ブロックで初期値を渡します。
例として以下のプログラムを実行してみて下さい。
# 初期値を「japan」とする配列を作成
country = Array.new(3) {'japan'}
# 配列の要素を変数に格納
s = country[0]
# 変数sに破壊的な変更を加える
s.upcase!
# 配列を表示
p country
実行結果の通り、一つ目の要素以外は変更されませんでした。
ブロックで初期値を設定すると、同じ値でも異なるオブジェクトを設定することができます。
尚、同じオブジェクトを参照しているかはオブジェクトIDで確認することができます。
# 引数で初期値を設定した場合のオブジェクトID
country1 = Array.new(3, 'japan')
puts '引数で初期値を設定した場合のオブジェクトID'
puts "要素1:#{country1[0].object_id}"
puts "要素2:#{country1[1].object_id}"
puts "要素3:#{country1[2].object_id}"
puts ""
# ブロックで初期値を設定した場合のオブジェクトID
country2 = Array.new(3) {'japan'}
puts 'ブロックで初期値を設定した場合のオブジェクトID'
puts "要素1:#{country2[0].object_id}"
puts "要素2:#{country2[1].object_id}"
puts "要素3:#{country2[2].object_id}"
要素1:47366969232680
要素2:47366969232680
要素3:47366969232680
ブロックで初期値を設定した場合のオブジェクトID
要素1:47366969232140
要素2:47366969232120
要素3:47366969232100
イミュータブルのオブジェクト
イミュータブルなオブジェクトでは、破壊的な変更が適用できません。
基本的なデータ型では、以下の4種類があります。
- 数値(IntegerクラスやFloatクラス)
- シンボル(Symbolクラス)
- true、false(TrueClassクラスとFalseClassクラス)
- nil(NilClassクラス)
最後に
今回はミュータブルとイミュータブルについて解説しました。
まずは文字列を扱う場合には注意が必要だと覚えておけば良いでしょう。
破壊的な変更を加えたことによる不具合を招かないためにも、ミュータブルとイミュータブルについてしっかり理解しておきましょう!
- 関連記事
Tomoyuki
最新記事 by Tomoyuki (全て見る)
- Go言語(Golang)専門の技術ブログ「Golang-Tech」を開設!? - 2024年9月26日
- 【2024年】モンハンワイルズの推奨スペックとおすすめのゲーミングPCを紹介! - 2024年9月26日
- 37歳Web系エンジニア3年目。生成AI(ChatGPT・Gemini)現る。 - 2024年7月3日
コメントを残す