2012-04-22 20 views
11

Noir webapp oluşturuyorum ve dinamik olarak yeni görünümler ve modeller oluşturmam gerekiyor. Bir kaynağın görünümü ve denetleyicisinin ayrı ad alanlarına sahip olduğu noir örneklerini takip ediyorum ve bunu çok temiz bir yaklaşım olarak buldum. Bununla uyumlu olarakDinamik olarak oluşturulmuş bir ad alanına işlev eklemek için temiz bir yol var mı?

, ben dinamik olarak onları görüş ve modelleri, ardından stajyer uygun fonksiyonlar tekabül yeni ad alanları oluşturmak gerekiyor. Benim fikrim, yeni ad alanında çağrıldığında, uygun rotaları/kısmi parçaları/her ne olursa olsun, ayrı bir isim alanında belirtilen makrolara sahip olmaktı. Örneğin

(benim ilk defmacro affet):

(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"]))) 

dan denir ...

(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) 

Ancak, benim yeni ad içinden bu çağırarak bana NullPointerException verir. Herhangi bir yardımı çok takdir ediyorum ve daha iyi bir yaklaşım olup olmadığına bakarım. Sadece gerekli tüm tanımları içeren bir isim alanına başvurmak gibi mi?

İlk gönderi ve bunun bir this tekrarı olduğunu sanmıyorum. Teşekkürler!

+0

Yayınınızı düzenlemeyi ve ad alanınızı ve makroyu çağıran bazı örnek Clojure kodlarını ifade etmeyi düşünür müsünüz? Hangi bağlamda kullanıldığını görmek isterim. tnx – octopusgrabbus

+1

Umarım bu biraz daha faydalıdır. – jtmoulia

+0

Aldığım hata şu simgeyi çözemiyor: bu bağlamda with-ns, derleme, ancak bunun bir işlev veya makro dışında -ns ile kullanılabildiğini bilmiyorum. – octopusgrabbus

cevap

1

Her şeyden önce, bu soru biraz modası geçmiş oldu. Hem Noir hem de Clojure geçen yıl gelişti. Netlik için, Noir'i denklemden çıkartacağım ve makroları kullanarak dinamik olarak fonksiyon oluşturma hakkındaki sorunuzu yanıtlamaya çalışacağım.

repl de birlikte takip edin: Burada

$ 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 

bir ad 'merhaba-adınız' işlevleri tanımlamak için bir makro içeriyor 'foo' oluşturmak. Başka bir ad yaratalım:

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 

bu gerçekten işe Bakalım:

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

Ben bu orijinal örneğe oldukça yakın olduğunu düşünüyorum.

Bu yardımcı olur umarız!