質問: 'こんにちは' puts TEISUU #=> こんにちは puts TEISUU.delete('に') #=>こんちは puts TEISUU #=> こんにちは puts TEISUU.delete!('に') #=>こんちは puts TEISUU #=>こんちは ```
回答: 著者の伊藤です。すでに解決済みなので回答が重複する部分もありますが、回答しておきます。 > > 何故delete!としていないのに定数の中身を破壊的に変更できるのでしょうか? > > > Rubyを学び始めたばかりの方はよく勘違いされるのですが、「!で終わる = 破壊的メソッド」ではありません。 2.11.3項にも書いたとおり、!で終わるメソッドは「使用する際に注意が必要」という意味です。 さらに、破壊的メソッドがすべて!で終わるとも限りません(同じく2.11.3項参照)。 もう一点付け加えると、「"!ありメソッド"がある場合は、"!なしメソッド"も定義しておく」という慣習もあるようです(これは「プロを目指す人のためのRuby入門」には書いていません)。 > > 以下のコードを実行したところ、deleteでは定数を破壊的に変更できず、delete!では変更可能でした > > > APIドキュメントを見てもらえればわかると思いますが、Stringクラスには`delete`と`delete!`の2種類がありますが、Arrayクラスには`delete`メソッドしかありません。 そして、StringクラスとArrayクラスは互いに無関係なクラスなので、たまたま`delete`という同じ名前のメソッドが定義されているだけです。 上記の議論を総合すると、「(Arrayクラスでは)何故delete!としていないのに定数の中身を破壊的に変更できるのでしょうか?」という問いに対しては、次のような回答が導出されます。 * !が付いているからといって破壊的メソッドとは限らない * !が付いていないからといって非破壊的メソッドとは限らない * !ありのメソッドが定義されている場合は、!なしの同名メソッドも定義した方がよい * Arrayクラスには(Stringクラスと異なり)delete系のメソッドが1種類しか定義されていない * 結果として、Arrayクラスには「破壊的な`delete`メソッド(!なしの破壊的メソッド)」のみが定義された とはいえ、このあたりの議論は、クラスライブラリの**設計**の話になります。 僕は自らの経験に基づいて上のような説明をしましたが、実際のところ(本当のいきさつ)はまつもとさん(Matz)や、コミッタのみなさんしかわからないと思います。 本当の真相を知りたい場合は、まつもとさんに「ねえ、どうして!?」と突撃インタビューするのが一番確実だと思います(笑)。