2010-09-21 27 views
9

Trong Clojure, làm cách nào để lấy tên của không gian tên trong đó các biến và hàm được đặt tên? Ví dụ, cải thiện điều sau đây:Clojure: đề cập đến tên của không gian tên

(ns my-ns) 

(def namespace-name "my-ns") 

Vấn đề với bên trên là nếu tôi muốn thay đổi tên của my-ns, tôi phải thay đổi định nghĩa của namespace tên tuổi cũng

Trả lời

11

Một sửa đổi đơn giản về câu trả lời của Arthur hoạt động tốt.

(def namespace-name (ns-name *ns*)) 

Tuy nhiên tôi muốn cảnh báo Clojure người mới bắt đầu mà

(defn namespace-name [] (ns-name *ns*)) 

sẽ không làm việc cho mục đích của câu hỏi này, vì * ns * là ràng buộc động.

+2

Nhưng một cái gì đó dọc theo dòng (defmacro defns-name [name] '(def ~ name (ns-name * ns *))) và sau đó gọi (defns-name namespace-name) sẽ hoạt động. –

+0

Markdown ăn các ngôi sao xung quanh 'ns' trong Nicolas bình luận ở trên: nên đọc:' (defmacro defns-name [name] \ '(def ~ tên (ns-name * ns *)))'. –

6

sự không gian tên hiện tại được lưu trữ trong

*ns* 

vì hàm của bạn được đánh giá trong thời gian chạy, bạn sẽ nhận được giá trị của * ns * khi bạn gọi nó.

vì vậy nếu bạn có thể muốn lưu một bản sao của nó.

+0

Bạn có nghĩa là (def không gian tên-name (ns tên \ * ns \ *))? – chris

+0

Tôi nhập * ns * và hiển thị dưới dạng chữ nghiêng? làm thế nào để tôi viết này để SO hiển thị nó theo nghĩa đen? –

+0

ahh nó đã làm nó một lần nữa! * ns * –

3

để tạo ra và lưu trữ một namespace, bạn có thể làm:

user=> (def working-namespace (create-ns 'my-namespace)) 
#'user/working-namespace 

user=> working-namespace 
#<Namespace my-namespace> 

user=> (class working-namespace) 
clojure.lang.Namespace 

bạn chỉ có một đối tượng không gian tên, nhưng tôi không thể cho bạn biết rất nhiều về những gì bạn có thể làm gì với nó. cho đến nay tôi chỉ biết của hàm tập thats chấp nhận một đối tượng Namespace

user=> (intern working-namespace 'my-var "somevalue") 
#'my-namespace/my-var 
1

ok, với sự giúp đỡ của anh chàng này, Michael Kohl, tôi phát hiện ra làm thế nào để chuyển sang một không gian tên được tổ chức tại một biến (read here for more details)

như vậy, ở đây chúng tôi đi:

user=> (def working-namespace (create-ns 'my-namespace)) 
#'user/working-namespace 
user=> (in-ns (symbol (str working-namespace))) 
#<Namespace my-namespace> 
my-namespace=> 
;; notice how it switched to "my-namespace" 

;; now if i were to put some other namespace in that variable... 
my-namespace=> (ns user) 
nil 
user=> (def working-namespace (create-ns 'other-namespace)) 
#'user/working-namespace 

;; and switch again, i would get the new namespace 
user=> (in-ns (symbol (str working-namespace))) 
#<Namespace other-namespace> 
other-namespace=> ; tadaa! 

mặc dù tôi không nghĩ rằng đó là clojure thành ngữ gán biến, bạn có thể xây dựng này thành một chức năng mà được các var giữ cho không gian tên như tham số

ngay để có được giá trị của một var bên trong và bên ngoài mà namespace

user=> (intern working-namespace 'some-var "my value") 
#'other-namespace/some-var 

user=> (var-get (intern working-namespace 'some-var)) 
"my value" 
Các vấn đề liên quan