前田です。
# Reply-To: ruby-dev / ruby-lang.orgです。

At Sat, 10 Mar 2001 23:05:03 +0900,
nobu.nakada / nifty.ne.jp wrote:
> > data=ARGF.readlines
> > data.each do |x|
> >   puts x if x =~ /45/
> > end
> > 
> > data=ARGF.readlines
> > data.each do |x|
> >   puts x if /45/ =~ x
> > end
> > はどう異なるのでしょうか。
> 
>   上は String#=~、下は Regexp#=~ が呼び出されます。つまり実行の
> 主体が違うわけですが、String#=~ は引数の Regexp に(必要なら変換
> してから)そっくり委譲してしまうので、動作としては同じです。デフォ
> ルトでは。

上はxがnilだとエラーになる、と思いこんでたのですがKernel#=~が呼ば
れますね。

bladeで検索したら以下のような記事が見つかりました。

[ruby-list:2061]:
> |それから些細な事ですが nil に対する =~ がなくなりましたね。
> |結構いい気になって使ってたので(使う方が悪いのだが)あっち
> |こっち直しました。
> 
> 相談せずに外して申し訳なかったですね.
> 
> 「Kernel#=~」は昔,caseの一致判定に「=~」を使っていた頃の名
> 残なので(今は「===」),もういらないかなと思って外しました.
> でも,「foo =~ /pattern/」に便利という側面もあるので,外さな
> い方が良かったのかなあ.

で、結局、

module Kernel
  def =~(other)
    return false
  end
end

となったわけですね。

でもこれだといかにもRegexpのためだけに追加したという感じで、nil +
1はエラーになるのにRegexpだけ特別あつかいなのは納得いかないような
気がするので、どうせなら、

module Kernel
  def =~(other)
    return other === self
  end
end

にしませんか?

あと、こういうのもありました。

[ruby-dev:996]:
> |nil =~ "foo" が undefined method `=~' になって
> |nil =~ /foo/ がエラーにならないのはなぜでしょう?
> |/foo/ =~ nil として扱われるから?
> 
> そうですね.=~の右辺が正規表現の時にはコンパイル時に両辺を取
> り換えたうえインライン展開しています(高速化のため).それを考
> えるとやっぱり Object#=~ とか NilClass#=~ とかを残しておくべ
> きだったかも知れませんね.

Kernel#=~が導入された今も、

irb(main):001:0> module Kernel; undef =~; end
nil
irb(main):002:0> nil.respond_to?(:=~)
false
irb(main):003:0> nil =~ /foo/
nil

という問題はありますね。

これが許されるなら定数の畳み込みとかもやってしまってもよいような
気がしなくもないですけどあんまり効果はないのかな。
=~はループ中に出て来ることが多いから効果があるんですかね。

-- 
前田 修吾