2011-09-03 71 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,你不得不嘗試將它打開,這不會很好。