Bladt
Bladt

Reputation: 305

common lisp (multiple) values both true and false?

I seem to have a cat-in-a-box kind of problem here The following code should, given a key and a hash-table, return the value corresponding to the key, or an error if the key is not present in the map:

(defun get-graph-node (key graph)
  (let ((result (gethash key graph)))
    (if (nth-value 1 result)
      (nth-value 0 result)
      (error "no node matches the key"))))

And for the most part it does, but I have this weird situation where running:

(gethash 0 *g*)

returns

   #S(GRAPH-NODE$
      :DATA "("$
      :EDGES (#S(GRAPH-NODE :DATA "b" :EDGES NIL)$
              #S(GRAPH-NODE :DATA "a" :EDGES NIL)))
   T

But

(get-graph-node 0 *g*)

Signals the error defined in get-graph-node

inspecting *g* gives me this:

Count: 5
Size: 16
Test: EQL
Rehash size: 1.5
Rehash threshold: 1.0
[clear hashtable]
Contents: 
0 = #S(GRAPH-NODE :DATA "(" :EDGES (#S(GRAPH-NODE :DATA "b" :EDGES NIL) #S(GRAPH-NODE :DATA "a" :EDGES NIL))) 
[remove entry]
1 = #S(GRAPH-NODE :DATA "a" :EDGES NIL) [remove entry]
2 = #S(GRAPH-NODE :DATA "|" :EDGES (#S(GRAPH-NODE :DATA ")" :EDGES (NIL)))) [remove entry]
3 = #S(GRAPH-NODE :DATA "b" :EDGES NIL) [remove entry]
4 = #S(GRAPH-NODE :DATA ")" :EDGES (NIL)) [remove entry]

So the key 0 should be in the map? A giant tip of my hat to the gentleman whom can tell me what I am missing.

Upvotes: 3

Views: 403

Answers (1)

jlahd
jlahd

Reputation: 6303

When assigning the result of gethash to the variable result, you are only storing the first of the multiple values returned by the function. To store them both, you should do something like this:

(defun get-graph-node (key graph)
  (multiple-value-bind (result exists)
      (gethash key graph)
    (if exists
      result
      (error "no node matches the key"))))

Upvotes: 6

Related Questions