From: Wakou Aoyama Date: 1998-10-31T05:38:33+09:00 Subject: [ruby-list:10525] Re: case with Class ちょっと case の歴史、というか、=== の歴史みたいなのがあった方が良さそ うですね。 昔々、Ruby には String 化症候群というのがありました。その頃、比較は =~ で行うというのが一般的に使われており、case もそのようになっていました。 case no when 1 when 2 end このような場合、String 化症候群により、no.to_s =~ 1.to_s のような比較 になっていました。 しかし、なんでも String 化してしまうというのは気持が悪いという事で、や がて String 化症候群は無くなっていきます。 すると、no =~ 1 という比較になりますが、String 以外にも =~ は変。かと いって、String の場合には =~ とし、それ以外では == というのも String だけを特別扱いするようで、これまた変。 そこで === の登場。 通常は == と同じ動作をし、String との場合(正確には、Regexp)は =~ の動 作をするというものです。 これで String 化症候群は無事なくなる事となりましたとさ。 (って、私はちょうどその移行後あたりから使い始めたので、正確では無いか もしれません。) また、String ではなく、Regexp というのは、 case "abc" when "a" when /a/ end このような場合、"a" ではなく、/a/ にマッチして欲しいものです。 そこで、比較を逆転し、"a" === "abc", /a/ === "abc" のようにしています。 つまり、String のメソッドの === は文字列としての比較。Regexp の === はパターンマッチというのを、逆転によりうまく使いわけているのです。 これにより、"a" にはマッチせず、/a/ に処理が流れるようになります。 さらに、このように case をより使いやすくするように、Array では比較する ものが配列に含まれるか、Range ではその範囲内に含まれるかといった判断の 動作をするように === を定義しています。 ですから、より正確には、=== は比較対象に合わせて挙動の変わる比較演算子 という事ではなく、case での比較時に便利なように各クラスで定義されている 単なる一メソッドという事になります。 従って、case での挙動については、各クラスの === の項目を見て調べるとい う事になります。 そして最後に、case での挙動をとりあえず === のマッチだけで確認してみよ うという場合、逆転されている事を忘れない事です。 先の例でいうと、"abc" === "a", "abc" === /a/ これはどちらも false にな りますからね。この結果から case の挙動を判断したりしないように注意しま しょう。 青山 和光 Wakou Aoyama