2011-01-19 13 views
15

use bunu yapardı, ancak geçerli ad alanında oluşturulan haritalama genel olarak görünmüyor.Başka bir isim alanına başvurabilir ve işlevlerini mevcut ns için herkese açık olarak gösterebilir miyim?

(ns my-ns-2 
    (:require [my-ns :as my])) 

(defn my-fct-2 
    [] 
    (my/another-fct 456)) ; this doesn't work 

ben another-ns çünkü bir kütüphane bir veritabanına erişmek için bunu yapmak istiyorum:

(ns my-ns 
    (:use [another-ns :only (another-fct)])) 

(defn my-fct 
    [] 
    (another-fct 123)) ; this works fine 

Sonra bu gibi başka bir ad var: İşte elde etmek istediğim şey bir örnektir . Bu kütüphaneye yapılan tüm aramaları tek bir isim alanında (my-ns) izole etmek istiyorum, bu şekilde tüm DB'ye bağımlı fonksiyonlar tek bir isim alanında izole edilecek ve gerekirse başka bir DB'ye geçiş yapmak daha kolay olacaktır.

Bu kitaplıktaki bazı işlevler benim için sorun değil, ancak diğerlerini de artırmak istiyorum. Okuma işlevlerinin iyi olduğunu söyleyeyim ancak yazma işlevlerini bazı doğrulamalarla artırmak istiyorum.

Şimdiye kadar gördüğüm tek yol, tüm eşlemeyi, büyütmediğim işlevler için bile my-ns'a el ile kodlamaktır.

cevap

8

bu yardımı mu? İşte

(defmacro pull [ns vlist] 
    `(do [email protected](for [i vlist] 
      `(def ~i ~(symbol (str ns "/" i)))))) 

bir örnek:

(ns my-ns) 

(defmacro pull [ns vlist] 
    `(do [email protected](for [i vlist] 
      `(def ~i ~(symbol (str ns "/" i)))))) 

(pull clojure.string (reverse replace)) 

(defn my-reverse 
    [] 
    (reverse "abc")) 

(ns my-ns-2) 

(defn my-fct-2 [] 
    (list (my-ns/my-reverse) 
     (my-ns/reverse "abc"))) 

(my-fct-2) 

sadece o, her şeyi çekmek istiyorsanız:

(defmacro pullall [ns] 
    `(do [email protected](for [i (map first (ns-publics ns))] 
      `(def ~i ~(symbol (str ns "/" i)))))) 

(pullall clojure.string) 
+0

Güzel bitti! Kabul işaretini sana değiştirdim. Teşekkürler. – Damien

+0

Hmm. Yararlı, ancak yalnızca işlevleri içeren ad alanlarıyla sınırlı gibi görünüyor: "Makro değerini alamıyor". –

11

Seçmeli olarak bunu yapmanın bir yolu (her bir işlevi açıkça belirtmek), Zach Tellman'ın Potemkin library gibi bir şey kullanmaktır. Bunun bir örneği, Lamina'nın halka açık giriş noktası olarak hizmet veren lamina.core ad alanı içinde, diğer tüm iç ad alanlarındaki önemli kamu işlevlerini içe aktarma biçiminde bulunur.

Ayrıca clojure.contrib.def/defalias kullanabilirsiniz:

(use 'clojure.contrib.def/defalias) 
(defalias foo clojure.string/blank?) 
(foo "") 
+0

Çok yardımcı, çok teşekkürler. – Damien

+5

Potemkin harika. Makro üzerinde çalışmayan kabul edilen yanıttan daha yararlı buldum. –

+0

'defalias' [gerçekte bir takma ad değil, bir kopya idi] (https://groups.google.com/d/msg/clojure/LhidPSlvX_Q/mS4R_52suXwJ) – beluchin

1

makro kullanımı bu

içinde tanımlanmış olabilir ad her şeyi çekin
(defmacro pullall [ns] 
    `(do [email protected](for [[sym var] (ns-publics ns)] 
      `(def ~sym ~var)))) 
İlgili konular