2012-04-22 82 views
11

我正在創建一個noir webapp,我需要動態創建新的視圖和模型。我一直在關注noir示例,其中資源的視圖和控制器具有不同的名稱空間,我發現它是一種非常乾淨的方法。有沒有一種乾淨的方式來添加功能到動態創建的命名空間?

與此相應地,我需要能夠動態地創建對應的視圖和模型,然後實習生相應的功能在他們新的命名空間。我的想法是在一個單獨的命名空間中指定宏,在新的命名空間中調用時,它將提供適當的路由/ partials/whatever。

例如(原諒我的第一個defmacro):

(ns project.views.proto 
    (:use noir.core 
     hiccup.core 
     hiccup.element 
     hiccup.form)) 

(defmacro def-all-page 
    [path] 
    `(defpage ~path [] 
    (html 
     [:h1 "Ya'll here"]))) 

從叫...

(ns project.proto 
    (:use [clojure.contrib.with-ns :only [with-ns]]) 

(create-ns 'foo) 
(intern 'foo 'path "path") ; In reality, the path is dynamic which is why I intern it 
(with-ns 'foo 
    (clojure.core/refer-clojure) 
    (use 'noir.core 
     'hiccup.core 
     'hiccup.element 
     '[project.views.proto :only [def-all-page]]) 

    (def-all-page path) 

但是,從我的新的命名空間中調用這給了我一個NullPointerException。我非常感謝任何幫助,以及是否有更好的方法。就像,只使用引用包含所有必要定義的名稱空間?

第一篇文章,我不認爲這是this重演。謝謝!

+0

你會考慮編輯你的文章,並指出你的名字空間和一些調用宏的示例Clojure代碼嗎?我想看看它在什麼情況下使用。 tnx – octopusgrabbus 2012-04-22 22:02:39

+1

我希望這會更有幫助。 – jtmoulia 2012-04-22 22:29:54

+0

我得到的錯誤是無法解析符號:在此上下文中帶-ns編譯,但我不知道這是否意味着您可以在函數或宏外使用-NS。 – octopusgrabbus 2012-04-22 22:38:48

回答

1

首先,這個問題已經變得有些過時了。 Noir和Clojure在去年都有進化。爲了清楚起見,我將Noir從等式中解釋出來,並嘗試回答有關使用宏動態創建函數的問題。

在REPL請跟隨:

$ lein repl 
user=> (in-ns 'foo) 
#<Namespace foo> 
foo=> (clojure.core/refer-clojure) 
nil 
foo=> (defmacro say-hello-to 
#_=>   [name] 
#_=>   `(defn ~(symbol (str "hello-" name)) 
#_=>     [] 
#_=>     ~(str "hello: " name))) 
#'foo/say-hello-to 

這裏我們創建一個命名空間「富」包含宏定義「你好,提供yourname」功能。讓我們創建另一個命名空間:

foo=> (in-ns 'bar) 
#<Namespace bar> 
bar=> (clojure.core/refer-clojure) 
nil 
bar=> (refer 'foo :only '[say-hello-to]) 
nil 
bar=> (say-hello-to "tom") 
#'bar/hello-tom 
bar=> (say-hello-to "jerry") 
#'bar/hello-jerry 

讓我們來看看這些實際工作:

bar=> (hello-tom) 
"hello: tom" 
bar=> (hello-jerry) 
"hello: jerry" 

我覺得這是非常接近你原來的例子。

希望這會有所幫助!

相關問題