rutoの日記: Rubyでcase文はパターン側の===演算子を呼ぶ
Haskellを使っているとパターンマッチ脳になってしまう。
するとRubyでもパターンマッチが使いたくなる。
Rubyではcase文(Cでいうところのswitch文)は===という演算子を使って場合分けをするというのを思い出して、
class Hoge
...
def ===(pattern)
...
end
...
end
case Hogeのインスタンス
when パターン
...
end
とやったのだがどうも上手くいかない。調べてみるとHogeで定義した===演算子が呼ばれていない。
Rubyのリファレンスマニュアルを見ると、「Hogeのインスタンス」の方ではなく「パターン」の方の===演算子が呼ばれるらしい。なので
class HogePattern
...
def ===(hoge)
...
end
...
end
case Hogeのインスタンス
when HogePattern::new(...)
...
end
としたら無事動いた。
よく考えてみるとこの設計は結構センス良いと思った。この設計なら別のPatternクラスを作ることによってHogePatternとは別の意味でマッチするようなパターンをいくらでも作れる。これがもしHoge側の===を使うようになっていたら1種類の意味でのマッチしか利用できない。
あとはパターンマッチしたときに変数が束縛されればいいのに。
myCase(Hogeのインスタンス).when(HogePattern::new(... VAR_PATTERN ... VAR_PATTERN ...) do |x, y|
end.when(パターン) do |a, b, c|
end.endCase
みたいなのを実装すればいいのか?
パターンはオブジェクトを受けとって配列を返す感じで。VAR_PATTERNは与えられたオブジェクトだけを含む配列を返す。
ちなみによく関数型言語とかで使われているパーザーコンビネーターもこんな感じで作られています。
Rubyでcase文はパターン側の===演算子を呼ぶ More ログイン