MyConundrum
MyConundrum

Reputation: 61

How do I add an instance of a struct to a hash table? I keep getting back a quoted list

I'm writing a simple little roguelike to learn racket. I am stuck on something that seems very simple -- creating a game-object factory using a hash table. The typical way I would do this (as in clojure or others) is create a keyword (like "player" and add an object instance for that type of game-object which I would then clone as needed.

I'm clearly missing something basic here. Sorry for the simple question.

I've tried multiple versions of creating the hash list. The only way I've gotten it to work is by simply putting the attributes in the hash list and instead of using struct-copy using apply. But this does not work well when their are nested structs inside the base struct.

;racket
#lang racket

(struct loc (x y) #:transparent)
(struct object (rep color loc) #:transparent)
(struct world (player running) #:transparent)

(define object-templates 
  #hash(["player" . (object "@" "green" (loc 0 0))]))

(define (make-object type) (struct-copy object (dict-ref object-templates type)))


; struct-copy: contract violation
;   expected: object?
;   given: '(object "@" "green" (loc 0 0))

I have no idea why I'm getting this as a quoted list. Instead of an instantiated object. I feel like I'm missing some syntactic sugar in the (define object-templates above, but I haven't been able to find it.

Upvotes: 4

Views: 211

Answers (1)

Sorawee Porncharoenwase
Sorawee Porncharoenwase

Reputation: 6502

Try:

(define object-templates 
  (hash "player" (object "@" "green" (loc 0 0))))

The problem is that #hash(...) will quote everything inside it. Use hash (or make-hash for mutable hash, though the argument format is different) if you want to allow evaluation.

This is similar to '(object) vs (list object), or #(object) vs (vector object), etc.

Upvotes: 6

Related Questions