2013-07-06 3 views
1

Je m'essaie à une aventure de texte dans clojure.Accéder à une variable globale par son nom dans Clojure

C'est là que je me bats:

(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))) 

Mon problème est avec la mise à jour l'emplacement var. Si j'entre (set-new-location hallway), cela fonctionne correctement. L'emplacement est défini sur la nouvelle pièce et je peux accéder à ses champs. Cependant, ce que je dois faire est de lire la prochaine sortie possible du champ de sortie d'une pièce, mais quand j'entre (set-new-direction (next-exit "west")) l'emplacement indique le couloir, mais il ne pointe pas vers la variable "couloir".

En CL je utiliserais (corridor de valeur de symbole). Comment puis-je faire ça à Clojure?

EDIT: Je veux vraiment utiliser var-per-location parce que j'ai esquissé environ 30 emplacements, à 20 lignes chacun, ce qui rend trop difficile à mettre dans une carte.

Répondre

3

Vous pouvez utiliser @(resolve sym) comme symbol-value de manière professionnelle; ce qu'il fait réellement est de rechercher le Var nommé par le symbole sym dans l'espace de noms actuel (peut être un Var introduit avec use/require :refer) et d'extraire sa valeur. Voir ns-resolve si vous voulez contrôler l'espace de nom du Var est recherché dans

Vous pouvez également ne pas utiliser Var-par-lieu, mais plutôt stocker vos emplacements dans une carte quelque part.

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

(Vous pourrait également mettre cette carte dans un Ref pour faciliter l'ajout de nouveaux emplacements à l'exécution.)

+0

Comment cela est-il supposé fonctionner? Si j'essaie '' (ref-set location @ (resolve bedroom)) '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' ''. – martin

+0

Vous auriez besoin de dire '@ (resolution 'bedroom)' (notez la citation) pour passer le symbole 'bedroom' à' resolve'. Bien sûr, si vous avez câblé un symbole particulier comme ça, il n'y a aucun intérêt à le faire et vous pouvez simplement écrire 'bedroom'; mais si le symbole est calculé dynamiquement, par exemple avec un appel à 'next-location', aucune citation supplémentaire ne sera nécessaire:' @ (resolve (next-location "west")) '. –

Questions connexes