表参道.rb #27 での発表に一部誤りがあったので訂正と補足
発表から一週間以上経ってしまっているんですが、発表中の発言に一部誤りがあったので訂正と補足。
pattern-match を使っているコードを説明する時に
「pattern-match は using PatternMatch をすることで match と with が使えるようになり〜」
と発言していたんですが、正しくは
「pattern-match は using PatternMatch をすることで match が使える」
でした。
pattern-match で使用している refinements では match のみが影響して with は関係ありませんでした。
では、なぜ with を使うことが出来るのかというと with を呼び出しているブロックは内部で #instance_eval されているためです。
#instance_eval を経由してブロックを呼び出すことで、評価するコンテキストが別になりブロック内で with を呼び出せるようになります。
class Env def with puts "with" end end def match &block # instance_eval で block を評価することで # block 内で Env のインスタンスメソッドを呼び出すことが出来る Env.new.instance_eval &block end match { with with with } # output: # with # with # with
この辺りの内部実装はもう少し解説すべきでしたね…申し訳ありませんでした。
ちなみに個人的には #match メソッドだけなら『Object#match で refinements する』のではなくて『module_function と定義して PatternMatch.match みたいな呼び出し』でもいいかなーとは思います。
PatternMatch. の部分が煩わしければ include PatternMatch とでもしておけばいいですしね。
まあここら辺はどちらがよいのかを考えるのがむずかしいところ…作りての好みもありますし。