在Clojure中按名称访问全局变量
我正在尝试在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
(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
。当然,如果你硬连线了一个特定的符号,那么这样做没有意义,你可以直接写卧室;但如果符号是动态计算的,例如通过调用下一个位置
,则无需额外引用:@(解析(下一个位置“西”)
。