Kimura Fuyuki
fuyuk****@hadal*****
2003年 1月 27日 (月) 08:46:32 JST
対案… - keys が与えられた場合、常にそのキーについて繰り返す。存在しないキー があっても重複があってもかまわない。 - (cursor 'exists?) を追加。 - update! と insert! は put! にまとめる。キーが存在するかどうかで処理 を分ける。 とすると、こんなふうになります。 (define-method call-with-iterator ((self <hash-table>) iteratee seed . keys) (let* ((inserted '()) (r (let loop ((keys (if (null? keys) (hash-table-keys self) keys)) (seed seed)) (if (null? keys) seed (let* ((key (car keys)) (exists? (hash-table-exists? self key))) (define (cursor method . args) (define (next seed) (loop (cdr keys) seed)) (define (get) (unless exists? (error "i don't exist")) (values key (hash-table-get self key))) (define (put! val) (cond (exists? (hash-table-put! self key val)) (else (push! inserted (cons key val))))) (define (delete!) (unless exists? (error "i don't exist")) (hash-table-delete! self key) (set! exists? #f)) (case method ((next) (apply next args)) ((get) (get)) ((put!) (apply put! args)) ((exists?) exists?) ((delete!) (delete!)) (else (error "speak english")))) (iteratee cursor seed)))))) (dolist (kv inserted) (hash-table-put! self (car kv) (cdr kv))) r)) ;; demos (define h (make-hash-table)) (define-method put! ((self <hash-table>) key val) (define (iteratee cursor seed) (cursor 'put! val)) (call-with-iterator self iteratee 0 key)) (define-method get ((self <hash-table>) key) (define (iteratee cursor seed) (cond ((cursor 'exists?) (receive (key val) (cursor 'get) val)) (else (error "dictionary doesn't have an entry for key" key)))) (call-with-iterator self iteratee 0 key)) (define-method get ((self <hash-table>) key default) (define (iteratee cursor seed) (cond ((cursor 'exists?) (receive (key val) (cursor 'get) val)) (else default))) (call-with-iterator self iteratee 0 key)) (put! h 'a 1) (put! h 'a 2) (print (get h 'a)) (print (get h 'b #f)) -- 木村 冬樹