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

时间:2013-07-06 09:03:13

标签: 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
                    "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位置。

如果我输入(set-new-location hallway),它就能正常工作。位置设置为新房间,我可以访问其字段。但是,我需要做的是从房间的退出区域读取下一个可能的退出,但是当我输入(set-new-direction (next-exit "west"))位置说走廊时,但它没有指向变量“走廊”。

在CL中我会使用(符号值走廊)。我怎么能在Clojure中做到这一点?

编辑:我真的想使用var-per-location因为我勾勒出大约30个位置,每个位置20行,这使得放置在一张地图中太笨重了。

1 个答案:

答案 0 :(得分:3)

您可以将@(resolve sym)用作symbol-value工作;它实际上做的是查找当前命名空间中符号sym命名的Var(可能是带有use / require :refer的Var)并提取其值。如果要控制查找Var的命名空间,请参阅ns-resolve

您也不能使用Var-per-location,而是将您的位置存储在某个地图中:

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

(您还可以将此地图放在参考中,以方便在运行时添加新位置。)