Does anybody know how to implement method_missing (à la Ruby) in Clojure? E.g.
(defn method_missing [name &开发者_运维问答 args]
(foo name args))
It would be very useful for a DSL, if used correctly.
Thanks in advance!
In Ruby, method_missing
is one of the primary constructs for metaprogramming. It's tightly bound to Ruby's object oriented structure, dynamically creating methods in a class from 'metaclasses'. This can be done because in Ruby classes are objects too.
Since Clojure is a functional language, mimicking this Rubyism makes little sense. However, one of the basic idioms of Lisps (such as Clojure), is that code is data: and as code can generate data, it can generate code also. The primary way to do this metaprogramming in Lisp is macros.
I'd suggest reading more about macros and their dos and don'ts. Be advised though that just like in Ruby, dynamically generated code is generally harder to debug and maintain. Often clever use of other functional idioms can be a better structural solution.
You could create a macro that would wrap function calls in a try-catch block that would catch this sort of exception.
e.g. Something like
(with-default-method [fxn args default] ...)
would expand to
(try (fxn args) (catch java.lang.IllegalArgumentException _) (finally default))
The above is mostly hand-waving, because I don't think that this is a good idea at all: it's abuse of the exception system, and I think it'll do unexpected things.
I'm not a Ruby person, but I get the feeling that this feature is baked into that language; in java, and by extension clojure, you'd have to try and bolt this on, and it wouldn't be pretty.
精彩评论