Ruby の初心者向け記事に数限りなく書かれてきた誤解の一つに,メソッド名末尾の !
についてのものがあります。
誤りにはいくつかのバリエーションがありますが,最も極端なものは
-
!
の付いたメソッドは破壊的 - そうでないメソッドは非破壊的
というものでしょう。
メソッドが破壊的というのは,レシーバーであるオブジェクトに変化を与えるということですね。
たとえば
"Ruby".upcase
の場合,upcase
メソッドは非破壊的で,レシーバーには変化を与えません。その代わり,レシーバーを元にしてそれを大文字化した,内容が「RUBY」であるような String オブジェクトを新たに生成して返します。
一方,
"Ruby".upcase!
の場合,新たなオブジェクトの生成は行われず,レシーバー自体の内容が大文字化されます。
返り値は,実際に変換が行われた場合(1 文字でも小文字が含まれていた場合)は self
であり,そうでない場合は nil
です。
この例ではまさに
-
!
の付いたメソッドは破壊的 - そうでないメソッドは非破壊的
となっています。
これが誤解の元になっているのですね。
確かに Ruby の組込みメソッドには,破壊版と非破壊版がペアになっていて,メソッド名末尾の !
の有無だけが異なるメソッドの組がたくさんあります。
しかし,これはそのような命名になっているというだけのことであり,Ruby の仕様ではありません。
また,組込みメソッドでも,!
の付かない破壊的メソッドはいくつもあります。
String
なら concat
や force_encoding
など。Array
なら shift
とか push
とかですね。
それから,!
の有無だけが違う命名のメソッドのペアが必ず破壊版・非破壊版というわけでもありません。
Rails だと ActiveRecord の create!
/create
でおなじみですね。