【Ruby】「!」の付かない破壊的メソッドまとめ

破壊的メソッドとは

オブジェクト自体を変えてしまうメソッドのことです。

array = ["hoge", "fuga", "piyo"]
array.slice(1..2)
p array # => ["hoge", "fuga", "piyo"]

例えば配列から要素を取り出してくれるsliceメソッドですが、あくまで取り出した要素を返してくれるだけで、その配列自体に変更を加えるわけではありません。

このようなものは「非破壊的メソッド」です。

array = ["hoge", "fuga", "piyo"]
array.slice!(1..2)
p array # => ["hoge"]

一方上のslice!は「破壊的メソッド」で、その配列自体に変更を加えます。

ちなみに破壊的メソッドの多くは!が付いており、メソッド名だけで破壊的だと判断できることが多いです。

array = ["hoge", "fuga", "piyo"]
array.delete_at(2)
p array # => ["hoge", "fuga"]

しかし上のdelete_atのように!が付かない破壊的メソッドもあります。これが本記事の主題になります。

「!」の付かない破壊的メソッド一覧

Stringクラス

concat・<<

txt = "hoge・fuga"
txt.concat("・piyo")
p txt # => "hoge・fuga・piyo"
txt = "hoge・fuga"
txt<<("・piyo")
p txt # => "hoge・fuga・piyo"

concatメソッドと<<メソッドは引数で指定した文字列を結合します。

insert

txt = "hoge・fuga"
txt.insert(-1, "・piyo")
p txt # => "hoge・fuga・piyo"

insertメソッドは引数で指定した所に文字列を挿入します。

[]=

txt = "hoge・fuga"
txt[-1] = "・piyo"
p txt # => "hoge・fuga・piyo"

[]=は引数で指定した箇所の文字を置き換えます。

replace

txt = "hoge"
p txt.object_id # => 70101500678680
txt.replace("fuga")
p txt # => "fuga"
p txt.object_id # => 70101500678680

replaceメソッドはその文字列自体を指定した文字列に置き換えます。あくまで置き換えなので同じオブジェクトのままです。

Arrayクラス

pop

array = ["hoge", "fuga", "piyo"]
array.pop
p array # => ["hoge", "fuga"]

popメソッドは配列の末尾の要素を削除します。

shift

array = ["hoge", "fuga", "piyo"]
array.shift
p array # => ["fuga", "piyo"]

shiftメソッドは配列の先頭の要素を削除します。

unshift

array = ["hoge", "fuga"]
array.unshift("piyo")
p array # => ["piyo", "hoge", "fuga"]

unshiftメソッドは引数に指定した要素を配列の先頭に追加します。

push・<<

array = ["hoge", "fuga"]
array.push("piyo")
p array # => ["hoge", "fuga", "piyo"]
array = ["hoge", "fuga"]
array.<<("piyo")
p array # => ["hoge", "fuga", "piyo"]

pushメソッドと<<メソッドは、引数に指定した要素を配列の末尾に追加します。

concat

array = ["hoge", "fuga"]
array.concat(["piyo"])
p array # => ["hoge", "fuga", "piyo"]

concatメソッドは引数に指定した配列を結合します。

insert

array = ["hoge", "piyo"]
array.insert(1, "fuga")
p array # => ["hoge", "fuga", "piyo"]

insertメソッドは引数で指定した所に要素を挿入します。

[]=

array = ["hoge", "fuga"]
array[1] = "piyo"
p array # => ["hoge", "fugpiyoa"]

[]=メソッドは引数で指定した所の要素を書き換えます。

fill

array = ["hoge", "fuga", "piyo"]
array.fill("hoge")
p array # => ["hoge", "hoge", "hoge"]

fillメソッドは配列の全要素を引数で指定した要素に変えます。

replace

array = ["hoge", "fuga", "piyo"]
p array.object_id # => 70104977327660
array.replace(["foo", "bar", "baz"])
p array # => ["foo", "bar", "baz"]
p array.object_id # => 70104977327660

replaceメソッドはその配列自体を指定した配列に置き換えます。あくまで置き換えなので同じオブジェクトのままです。

delete

array = ["hoge", "fuga", "piyo"]
array.delete("hoge")
p array # => ["fuga", "piyo"]

deleteメソッドは引数で指定した要素を配列から削除します。

delete_at

array = ["hoge", "fuga", "piyo"]
array.delete_at(0)
p array # => ["fuga", "piyo"]

delete_atメソッドは引数で指定したインデックスの要素を配列から削除します。

delete_if

array = ["hoge", "fuga", "piyo"]
array.delete_if do |item| item =~ /^h/ end
p array # => ["fuga", "piyo"]

delete_ifメソッドは引数のブロックの条件を満たす要素を配列から削除します。

clear

array = ["hoge", "fuga", "piyo"]
array.clear
p array # => []

`clearメソッドは配列を空にします。

Hashクラス

shift

hash = {name: "hoge", age: 20}
hash.shift
p hash # => {age: 20}

shiftメソッドはハッシュ先頭のキーと値を削除します。

replace

hash = {name: "hoge", age: 20}
p hash.object_id # => 70120001276640
hash.relace({name: "fuga", age: 30})
p hash # => {name: "fuga", age: 30}
p hash.object_id # => 70120001276640

replaceメソッドはそのハッシュ自体を指定したハッシュに置き換えます。あくまで置き換えなので同じオブジェクトのままです。

update

hash = {name: "hoge", age: 20}
hash.update({name: "fuga", sex: "men"})
p hash # => {name: "fuga", age: 20, sex: "men"}

updateメソッドは引数で指定したハッシュと結合させます。既存のキーと同じものがある場合更新されます。

delete

hash = {name: "hoge", age: 20}
hash.delete(:age)
p hash # => {name: "hoge"}

deleteメソッドは引数で指定したキーの要素を削除します。

delete_if

hash = {name: "hoge", age: 20}
hash.delete_if do |key, value| key =~ /^\d+?$/ end
p hash # => {name: "hoge"}

clear

hash = {name: "hoge", age: 20}
hash.clear
p hash # => {}

clearメソッドはハッシュを空にします。

注意点

返り値について

array = ["hoge", "fuga", "piyo"]
p a.delete("hoge") # => "hoge"

破壊的メソッドの中には、その変更したオブジェクトが返り値とならないものがあります。

例えば上のdeleteメソッドですが、ここでは消した要素そのものが返っていますね。

Stringクラスのdeleteメソッド

txt = "hoge"
txt.delte("h")
p txt # => "hoge"

ArrayクラスとHashクラスのdeleteメソッドは破壊的ですが、Stringクラスのdeleteメソッドは非破壊的です。