Clojure では、if
条件に一致しない式の分岐は評価されないため、以下の式の評価で例外はスローされません。
=> (if nil (/ 1 0))
nil
ただし、マクロは を評価する前に展開されるため、次のif
ような例外が発生する可能性があります。
=> (if nil (proxy [nil] []))
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1)
インターフェイスの名前が引数として提供されることがあるマクロを作成しています。この場合、マクロは への呼び出しのコードを生成しますproxy
。それ以外の場合は、インターフェイス引数が になりnil
、マクロが のようなものに展開される(if nil (proxy [nil] [])
ため、上記の例外が発生します。SSCE は次のようになります。
=> (defmacro make-listener [listener-name & methods]
`(if ~listener-name
(proxy [~listener-name] []
~@(map (fn [m] `(~m [e#])) methods))))
#'user/make-listener
=> (make-listener java.awt.event.ActionListener actionPerformed)
#<Object$ActionListener$46793e3a user.proxy$java.lang.Object$ActionListener$46793e3a@ed5b2>
=> (make-listener nil)
CompilerException java.lang.NullPointerException, compiling:(NO_SOURCE_PATH:1)
インターフェイス引数が指定されていない場合に例外をスローしない方法でマクロを作成するにはどうすればよいですか?