ClojureのderefをいじくるPart2

2010-03-09 - 壊れた計算機のときはproxyを使ってclojure.lang.IDerefのderefをオーバーライドしていたが、今回はclojure.core/derefをそのままいじくった。derefをmultimethodに置きかえて、正規表現をderefしたらre-seqする関数を返すように変更してみた。ほんのりとリーダマクロに近いことができた(別にリーダマクロにこだわっているわけではないけど)。

(ns generic.deref
    (:refer-clojure :exclude [deref]))

(def clojure-core-deref clojure.core/deref)

(defmulti deref type)
(defmethod deref :default [x]
  (clojure-core-deref x))
(defmethod deref java.util.regex.Pattern [re]
  (fn [s] (re-seq re s)))

(intern 'clojure.core 'deref generic.deref/deref)
@(atom 0) ;=> 0
@#"[rR]egexp" ;=> #<deref$ ... generic.deref$eval__18$fn__20$fn__22@f8622f3>
(@#"\d+" "aa123aa90a") ;=> ("123" "90")

generic.derefを使わない場合は↓のようになる。

@#"[rR]egexp" ;=> ... java.util.regex.Pattern cannot be cast to clojure.lang.IDeref ...