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