🗂
[Ruby] String、Regexクラスでの`===`の挙動の違い
以下のコードの挙動を検証します。
> 'hoge' === /h/
=> false
> /h/ === 'hoge'
=> true
このように、String#===
とRegex#===
は似ているようで挙動が違います。
ではなぜこうなるのでしょうか。
String#===
の場合
> 'hoge' === /h/
=> false
class String (Ruby 3.2 リファレンスマニュアル)には、
other が文字列の場合、String#eql? と同様に文字列の内容を比較します。
other が文字列でない場合、 other.to_str が定義されていれば other == self の結果を返します。(ただし、 other.to_str は実行されません。) そうでなければ false を返します。
とあります。
/h/.class
はRegexpクラスであり、/h/.to_str
をするとNoMethodError
が発生します。
> /h/.class
=> Regexp
> /h/.to_str
(irb):5:in `<main>': undefined method `to_str' for /h/:Regexp (NoMethodError)
したがって、結果はfalse
になります。
Regex#===
の場合
> /h/ === 'hoge'
=> true
こちらはシンプルに正規表現として機能しています。
-
/h/
という正規表現が、'hoge'
という文字列のどれかにマッチするか検証している - この場合、
'hoge'
という文字列の中にh
が含まれているのでtrue
を返す
Discussion