Hold the saved values weakly.
This commit is contained in:
parent
cc82506be5
commit
cda4479d1e
|
@ -87,6 +87,9 @@
|
||||||
4
|
4
|
||||||
-> «(list ^ ^^ ^^^ ^^^^)»
|
-> «(list ^ ^^ ^^^ ^^^^)»
|
||||||
'(4 3 2 1)
|
'(4 3 2 1)
|
||||||
|
-> «(collect-garbage)»
|
||||||
|
-> «^»
|
||||||
|
; ^: saved value #1 was garbage-collected [,bt for context]
|
||||||
-> «(module foo racket (define x 123))»
|
-> «(module foo racket (define x 123))»
|
||||||
-> «,en foo»
|
-> «,en foo»
|
||||||
'foo> «x»
|
'foo> «x»
|
||||||
|
|
|
@ -49,7 +49,12 @@
|
||||||
[else (err "unknown name pattern for a saved-value reference")]))
|
[else (err "unknown name pattern for a saved-value reference")]))
|
||||||
(unless (pair? saved) (err "no saved values, yet"))
|
(unless (pair? saved) (err "no saved values, yet"))
|
||||||
(when (n . > . (length saved)) (err "no ~a saved values, yet" n))
|
(when (n . > . (length saved)) (err "no ~a saved values, yet" n))
|
||||||
#`'#,(list-ref saved (sub1 n)))
|
;; the values are either `#f', or a weak box holding the value
|
||||||
|
(define r
|
||||||
|
(let ([b (list-ref saved (sub1 n))])
|
||||||
|
(and b (or (weak-box-value b)
|
||||||
|
(err "saved value #~a was garbage-collected" n)))))
|
||||||
|
#`'#,r)
|
||||||
(syntax-case stx (set!)
|
(syntax-case stx (set!)
|
||||||
[(set! id . xs) (raise-syntax-error 'set! "cannot set history reference")]
|
[(set! id . xs) (raise-syntax-error 'set! "cannot set history reference")]
|
||||||
[(id . xs) (datum->syntax stx (cons (ref #'id) #'xs) stx)]
|
[(id . xs) (datum->syntax stx (cons (ref #'id) #'xs) stx)]
|
||||||
|
|
|
@ -1198,7 +1198,8 @@
|
||||||
;; saved interaction values (can be #f to disable saving)
|
;; saved interaction values (can be #f to disable saving)
|
||||||
(define saved-values (make-parameter '()))
|
(define saved-values (make-parameter '()))
|
||||||
(define (save-values! xs)
|
(define (save-values! xs)
|
||||||
(let ([xs (filter (λ (x) (not (void? x))) xs)]) ; don't save void values
|
(let* ([xs (filter (λ (x) (not (void? x))) xs)] ; don't save void values
|
||||||
|
[xs (map (λ (x) (and x (make-weak-box x))) xs)]) ; save weakly
|
||||||
(unless (null? xs)
|
(unless (null? xs)
|
||||||
;; the order is last, 2nd-to-last, ..., same from prev interactions
|
;; the order is last, 2nd-to-last, ..., same from prev interactions
|
||||||
;; the idea is that `^', `^^', etc refer to the values as displayed
|
;; the idea is that `^', `^^', etc refer to the values as displayed
|
||||||
|
|
|
@ -451,9 +451,19 @@ The rationale for this is that @racketidfont{^} always refers to the
|
||||||
last @emph{printed} result, @racketidfont{^^} to the one before that,
|
last @emph{printed} result, @racketidfont{^^} to the one before that,
|
||||||
etc.
|
etc.
|
||||||
|
|
||||||
These bindings are made available only if they are not already defined,
|
The bindings are made available only if they are not already defined.
|
||||||
and if they are not modified. This means that if you have code that
|
This means that if you have code that uses these names, it will continue
|
||||||
uses these names, it will continue to work as usual.
|
to work as usual.
|
||||||
|
|
||||||
|
The bindings are identifier macros that expand to the literal saved
|
||||||
|
values; so referring to a saved value that is missing (because not
|
||||||
|
enough values were shown) raises a syntax error. In addition, the
|
||||||
|
values are held in a @tech{weak reference}, so they can disappear after
|
||||||
|
a garbage-collection.
|
||||||
|
|
||||||
|
Note that this facility can be used to ``transfer'' values from one
|
||||||
|
namespace to another---but beware of struct values that might come from
|
||||||
|
a different instantiation of a module.
|
||||||
|
|
||||||
@; ---------------------------------------------------------------------
|
@; ---------------------------------------------------------------------
|
||||||
@section{Hacking XREPL}
|
@section{Hacking XREPL}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user