2013-04-18 87 views
3

如果我有一个符号名称空间是别名,比如q/w,我怎么能找到它的实际名称空间,比如说actual.namespace/w?如何查找符号的完全限定名称空间?

我知道resolve会给我完全合格的变种,但我不知道如何获得变种的名称空间。

我能做的最好的是:

(defn fqns [s] (str (get (ns-aliases *ns*) (symbol (namespace s))))) 

肯定有一个简单的方法?

回答

7

你可以得到一个符号的命名空间对象,如下图所示(如果你想纳秒为字符串的名称,然后就叫末STR):

(defn fqns [s] (->> (resolve s) meta :ns)) 
2

本身具有任何没有直接连接符号命名空间对象;它的命名空间部分只是一个实际的字符串。只有当它是resolve d时,该字符串才被视为在其中查找Var的实际名称空间的名称。 (特别是,您可以创建一个符号foo/bar,而不创建名称空间foo或注册foo作为命名空间的别名。)因此,您需要通过resolve或自己完成部分工作。

在第一种情况下,你可以说(在最新版本的Clojure的;或者你可以跳过连字符标志着属性访问 - 而不是-ns,使用ns - 是向后兼容)

(.. (resolve s) -ns -name) 

这将解析Var对象,然后从其ns字段中提取对其名称空间的引用,最后从其name字段中提取名称空间的符号名称。 (请注意,namespacename功能是行不通的,因为瓦尔和命名空间不落实clojure.lang.Named

从问题文本的功能也没关系,但它会更好地提取从符号名命名空间 - (.-name (get ...)) - 通过使用str而不是依赖名称空间的toString表示。

您可能还需要添加clojure.lang.Varclojure.lang.Namespace键入提示,以避免在通话中反映出来。 (如果你希望他们更快,或者如果您需要*warn-on-reflection*扭捏别的性能和希望避免在这里没用的警告。)

如果要处理的命名空间不存在的可能性(和返回nil在这种情况下,与平常的Clojure成语)保持:

(defn fqns 
    ([s] 
    (fqns (.-name *ns*) s)) 
    ([ns s] 
    (some-> ns 
      find-ns 
      .-name 
      ns-aliases 
      (get (symbol (namespace s))) 
      .-name))) 

或者用Clojure 1.4使用一些if-let S和更早版本。

相关问题