在Clojure中按名称访问全局变量

在Clojure中按名称访问全局变量,clojure,Clojure,我正在尝试在clojure进行文本冒险 这就是我奋斗的地方: (ns records) (defrecord Room [fdesc sdesc ldesc exit seen]) (defrecord Item [name location adjective fdesc ldesc sdesc flags action ]) (def bedroom (Room. "A lot of text." nil

我正在尝试在clojure进行文本冒险

这就是我奋斗的地方:

(ns records)


(defrecord Room [fdesc sdesc ldesc exit seen])

(defrecord Item [name location adjective fdesc ldesc sdesc flags action ])

(def bedroom (Room. "A lot of text."
                    nil
                    "some text"
                    '(( "west" hallway wearing-clothes? wear-clothes-f))
                    false))

(def hallway (Room. "description of room."
                            nil
                           "short desc of room."
                           '(("east" bedroom) ("west" frontdoor))
                           false))

(def location (ref bedroom))

(defn in?
  "Check if sequence contains item."
  [item lst]
  (some #(= item %) lst))

(defn next-location
  "return the location for a entered direction"
  [direction ] 
  (second (first (filter #(in? direction %) (:exit @location)))))

(defn set-new-location
  "set location parameter to new location."
  [loc]
  (dosync (ref-set location loc)))
我的问题是更新var位置

如果我输入
(设置新位置走廊)
,它将正常工作。位置设置为新房间,我可以访问其字段。但是,我需要做的是从房间的出口字段中读取下一个可能的出口,但是当我输入
(设置新方向(下一个出口“west”)
位置显示为hallway,但它不指向变量“hallway”

在CL中,我会使用(符号值走廊)。在Clojure我怎么做

编辑:我真的想在每个位置使用var,因为我已经画出了大约30个位置,每个位置有20行,这使得在一个地图中放置它太难了。

你可以使用
@(解析sym)
作为
符号值;它实际做的是在当前名称空间中查找由符号
sym
命名的变量(可能是随
use
/
require:refere
引入的变量)并提取其值。如果要控制在其中查找变量的命名空间,请参见
ns resolve

您也可以不使用每个位置的Var,而是将您的位置存储在地图中的某个位置:

(def locations {:hallway ... :bedroom ...})

(为了方便在运行时添加新位置,您也可以将此地图放在Ref中。)

这应该如何工作?如果我尝试
(ref set location@(resolve dombery))
我会得到
ClassCastException记录。房间不能转换为clojure.lang.Symbol clojure.core/ns-resolve(core.clj:3954)
。你需要说
@(resolve'dombery)
(注意引号)才能将符号
dombery
传递到
resolve
。当然,如果你硬连线了一个特定的符号,那么这样做没有意义,你可以直接写
卧室
;但如果符号是动态计算的,例如通过调用
下一个位置
,则无需额外引用:
@(解析(下一个位置“西”)