2011-09-03 58 views
7

有人知道如何在Clojure中实现method_missing(àla Ruby)吗? 例如丢失Clojure方法

(defn method_missing [name & args] 
    (foo name args)) 

如果使用正确的话,这对于DSL是非常有用的。

在此先感谢!

+2

您希望在什么情况下调用此函数? – Brian

回答

10

在Ruby中,method_missing是元编程的主要构造之一。它紧密地绑定到Ruby的面向对象的结构上,从“元类”中动态地创建类中的方法。这可以做到,因为在Ruby类中也是对象。

因为Clojure是一种功能性语言,所以模仿Rubyism没什么意义。然而,Lisp的基本习惯之一(比如Clojure)就是代码是数据:而代码可以生成数据,它也可以生成代码。在Lisp中进行元编程的主要方法是宏。

我建议阅读更多关于宏以及它们的注意事项和注意事项。尽管如此,就像在Ruby中一样,动态生成的代码通常很难调试和维护。聪明地使用其他功能性习语可能是更好的结构性解决方案。

+3

我同意这一点,但我反对声明动态生成的代码很难调试或维护。假如它们被高雅地使用,宏为简化和可维护性带来了巨大的益处。 – amalloy

+0

只是想指出什么时候使用宏应该被认真考虑,并且当你可以用普通函数做一些事情时,这应该是首选。 – NielsK

+1

自己来自Ruby,我发现可能需要一段时间才能掌握函数组合的力量。使用宏来解决这个问题可能会适得其反。 – NielsK

5

您可以创建一个将函数调用包装在try-catch块中的宏,以捕获这类异常。

例如像

(with-default-method [fxn args default] ...) 

东西将扩大到

(try (fxn args) (catch java.lang.IllegalArgumentException _) (finally default)) 

以上主要是挥手,因为我不认为这是一个好主意都:这是异常系统的滥用,并我认为它会做出意想不到的事情。

我不是Ruby的人,但我觉得这个功能被烘焙到那种语言中;在java中,通过扩展clojure,你不得不尝试将它打开,这不会很好。