Rubyにおいて暗黙の型変換を試みるメソッドを探す(途中)

たとえば "hoge" + 1 のような処理をするとき、足す側の値が String でない場合、暗黙的に to_str メソッドを実行して String に変換しようとします。

これを暗黙の型変換と呼ぶらしいですが、 + 演算子以外でこのような裏の処理を行うメソッドって他に何があるのかな?ってのが気になりました。

気にはなったんですが、どこかにまとまっているとかはなさそう…。なので、るりまサーチで「暗黙の」で検索してみました。ってかるりまサーチってメソッド名とかじゃなくても検索できるの初めて知った…。

https://docs.ruby-lang.org/ja/search/query:%E6%9A%97%E9%BB%99%E3%81%AE/

結果、406件がヒット。多いぇ…!wとは言え、これは知見の塊な予感がするので、眺めてみようと思います。

例えば、Array#zip の場合、引数が Array でなかった場合に暗黙の型変換 to_ary を試みます。以下の例だと、引数が String の場合は TypeError。 Hash の場合は to_ary メソッドが定義されているので、そのまま Array に変換されて処理が続きます。

[1, 2, 3].zip("hoge")
=> TypeError: wrong argument type String (must respond to :each)

[1, 2, 3].zip(hoge: 1)
=> [[1, [:hoge, 1]], [2, nil], [3, nil]]

Array#[]= の例はわかりやすいかも。インデックスに指定する値が Integer 以外の場合、暗黙の型変換 to_int を試みます。これが失敗した場合 TypeError を返します。

[][:hoge] = 1
=> TypeError: no implicit conversion of Symbol into Integer

ところが、暗黙の型変換を行う用のメソッド to_str とかがない場合でも明示的な型変換メソッドも試みるパターンもあるようです。

Array#join がそのパターンです。

文字列でない要素に対しては、to_str があれば to_str、なければ to_s した結果を連結します。
["foo", nil, 1, 1.0].join
=> "foo11.0"

通常 nil や 1 や 1.0 には to_str メソッドは定義されていませんが、その場合は to_s メソッドが実行されるので、Array#join の場合はエラーは起こりません。こういうパターンもあるのか…。

これ全部読んでいったらすごい量の note になってしまうのでここらへんにしておきますが、こういう例もあるというのはかなりの知見でした。ありがとうございます、るりま…。