Rewrite hash-keys so that only keys, not values, are accessed.

This distinction is important after the introduction of chaperones and
impersonators, since accessing a key and accessing its corresponding value
may have different effects, and hash-keys should only trigger the former.
This commit is contained in:
Stevie Strickland 2012-04-03 12:52:03 -04:00
parent d635b93644
commit f37ff698b4
2 changed files with 37 additions and 2 deletions

View File

@ -1,6 +1,10 @@
(module hash "pre-base.rkt" (module hash "pre-base.rkt"
(define (hash-keys table) (define (hash-keys h)
(hash-map table (λ (k v) k))) (let loop ([pos (hash-iterate-first h)])
(if pos
(cons (hash-iterate-key h pos)
(loop (hash-iterate-next h pos)))
null)))
(define (hash-values table) (define (hash-values table)
(hash-map table (λ (k v) v))) (hash-map table (λ (k v) v)))

View File

@ -1238,6 +1238,37 @@
(print ht o) (print ht o)
(get-output-string o)))) (get-output-string o))))
;; ----------------------------------------
;; Check that only key-proc is called during hash-keys
(as-chaperone-or-impersonator
([chaperone-hash impersonate-hash])
(let* ([h1 (make-hash (list (cons 1 2) (cons 3 4) (cons 5 6) (cons 7 8)))]
[res1 (hash-keys h1)]
[ref-proc #f]
[set-proc #f]
[remove-proc #f]
[key-proc #f]
[h2 (chaperone-hash h1
(λ (h k)
(set! ref-proc #t)
(values k (λ (h k v) v)))
(λ (h k v)
(set! set-proc #t)
(values k v))
(λ (h k)
(set! remove-proc #t)
k)
(λ (h k)
(set! key-proc #t)
k))]
[res2 (hash-keys h2)])
(test #t equal? res1 res2)
(test #t values key-proc)
(test #f values ref-proc)
(test #f values set-proc)
(test #f values remove-proc)))
;; ---------------------------------------- ;; ----------------------------------------
(report-errs) (report-errs)