破壊的メソッド
破壊的メソッドはオブジェクトの値を変更してしまうもの。
同一名のメソッドが存在する場合に破壊的メソッドと非破壊的メソッドのバージョンがある場合、破壊的な方に!
をつけて命名する慣習がある。
破壊的メソッド全てに!
が書かれているわけではなくArrayの#shift
や#pop
など!
がつかなくとも破壊的であることはある。
非破壊的
collect
を使用して配列の値を5倍にしてみる。
非破壊的
a1 = (1..5).to_a
a2 = a1
puts "a1:#{a1}"
puts "a2:#{a2}"
a3 = a1.collect{|item| item * 5}
#値を確認
puts "a1:#{a1}"
puts "a2:#{a2}"
puts "a3:#{a3}"
#オブジェクトが同じか確認
p a1.equal?(a2)
p a2.equal?(a3)
p a1.object_id
p a2.object_id
p a3.object_id
a1:[1, 2, 3, 4, 5]
a2:[1, 2, 3, 4, 5]
a1:[1, 2, 3, 4, 5]
a2:[1, 2, 3, 4, 5]
a3:[5, 10, 15, 20, 25]
true
false
70280240326200
70280240326200
70280240325660
非破壊的な場合は使用したオブジェクトの値は変更されていない。
object_id
を確認するとa3は新たなオブジェクトとして生成されていることを確認できる。
破壊的
collect
に!
をつけて実行する
破壊的
a1 = (1..5).to_a
a2 = a1
puts "a1:#{a1}"
puts "a2:#{a2}"
a3 = a1.collect!{|item| item * 5}
#値を確認
puts "a1:#{a1}"
puts "a2:#{a2}"
puts "a3:#{a3}"
#オブジェクトが同じか確認
p a1.equal?(a2)
p a2.equal?(a3)
p a1.object_id
p a2.object_id
p a3.object_id
a1:[1, 2, 3, 4, 5]
a2:[1, 2, 3, 4, 5]
a1:[5, 10, 15, 20, 25]
a2:[5, 10, 15, 20, 25]
a3:[5, 10, 15, 20, 25]
true
true
70138750133780
70138750133780
70138750133780
呼び出したオブジェクトの値と参照していたa2も変更される。
a3は新しいオブジェクトとしては生成されず同一のオブジェクトとなっている。