Add procedure? as an acceptable type for prop:serialize's deserialize binder. (#2168)
* Add allow the binder in prop:serialize to be a procedure. This procedure is evaluated at serialize time, and is useful if the deserializer is not known during object-type creation time, but is during serialize time. * Add docs+tests. * Add a history note.
This commit is contained in:
parent
cc4daf074f
commit
99fff46726
|
@ -556,7 +556,8 @@ serializable. The property value should be constructed with
|
|||
[deserialize-id (or identifier?
|
||||
symbol?
|
||||
(cons/c symbol?
|
||||
module-path-index?))]
|
||||
module-path-index?)
|
||||
(-> any/c))]
|
||||
[can-cycle? any/c]
|
||||
[dir path-string?])
|
||||
any]{
|
||||
|
@ -590,6 +591,10 @@ must be one of the following:
|
|||
a symbol to name an exported identifier, and the @racket[cdr] must be
|
||||
a module path index to specify the exporting module.}
|
||||
|
||||
@item{If @racket[deserialize-id] is a procedure, then it is
|
||||
applied during serialization and its result is used for
|
||||
@racket[deserialize-id].}
|
||||
|
||||
]
|
||||
|
||||
See @racket[make-deserialize-info] and @racket[deserialize] for more
|
||||
|
@ -605,7 +610,9 @@ resolve a module reference for the binding of @racket[deserialize-id].
|
|||
This directory path is used as a last resort when
|
||||
@racket[deserialize-id] indicates a module that was loaded through a
|
||||
relative path with respect to the top level. Usually, it should be
|
||||
@racket[(or (current-load-relative-directory) (current-directory))].}
|
||||
@racket[(or (current-load-relative-directory) (current-directory))].
|
||||
|
||||
@history[#:changed "7.0.0.6" @elem{Allow @racket[deserialize-id] to be a procedure.}]}
|
||||
|
||||
@examples[
|
||||
#:eval ser-eval
|
||||
|
|
|
@ -635,4 +635,36 @@
|
|||
|
||||
;; ----------------------------------------
|
||||
|
||||
(module interchange-deserialize racket/base
|
||||
(provide (all-defined-out))
|
||||
(require racket/serialize)
|
||||
(define current-des #'interchange-des-a)
|
||||
(define (set-current-des! val)
|
||||
(set! current-des val))
|
||||
(struct interchange ()
|
||||
#:property prop:serializable
|
||||
(make-serialize-info
|
||||
(λ (this) (vector))
|
||||
(λ () current-des)
|
||||
#t
|
||||
(or (current-load-relative-directory) (current-directory))))
|
||||
(define interchange-des-a
|
||||
(make-deserialize-info
|
||||
(λ () 42)
|
||||
(λ ()
|
||||
(values 42
|
||||
(λ (other) (void))))))
|
||||
(define interchange-des-b
|
||||
(make-deserialize-info
|
||||
(λ () 43)
|
||||
(λ ()
|
||||
(values 43
|
||||
(λ (other) (void)))))))
|
||||
(require 'interchange-deserialize)
|
||||
(test 42 'interchange-default (deserialize (serialize (interchange))))
|
||||
(set-current-des! #'interchange-des-b)
|
||||
(test 43 'interchange-alternate (deserialize (serialize (interchange))))
|
||||
|
||||
;; ----------------------------------------
|
||||
|
||||
(report-errs)
|
||||
|
|
|
@ -118,43 +118,46 @@
|
|||
(hash-ref
|
||||
cache deserialize-id
|
||||
(lambda ()
|
||||
(let ([id
|
||||
(let ([path+name
|
||||
(cond
|
||||
[(identifier? deserialize-id)
|
||||
(let ([b (identifier-binding deserialize-id (variable-reference->phase varref))])
|
||||
(cons
|
||||
(and (list? b)
|
||||
(if (symbol? (caddr b))
|
||||
(caddr b)
|
||||
(protect-path
|
||||
(collapse/resolve-module-path-index
|
||||
(caddr b)
|
||||
(build-path (serialize-info-dir info)
|
||||
"here.ss"))
|
||||
rel-to)))
|
||||
(syntax-e deserialize-id)))]
|
||||
[(symbol? deserialize-id)
|
||||
(cons #f deserialize-id)]
|
||||
[else
|
||||
(cons
|
||||
(if (symbol? (cdr deserialize-id))
|
||||
(cdr deserialize-id)
|
||||
(protect-path
|
||||
(collapse/resolve-module-path-index
|
||||
(cdr deserialize-id)
|
||||
(build-path (serialize-info-dir info)
|
||||
"here.ss"))
|
||||
rel-to))
|
||||
(car deserialize-id))])])
|
||||
(hash-ref
|
||||
mod-map path+name
|
||||
(lambda ()
|
||||
(let ([id (hash-count mod-map)])
|
||||
(hash-set! mod-map path+name id)
|
||||
id))))])
|
||||
(hash-set! cache deserialize-id id)
|
||||
id)))))
|
||||
(define id
|
||||
(let ([path+name
|
||||
(let loop ([deserialize-id deserialize-id])
|
||||
(cond
|
||||
[(procedure? deserialize-id)
|
||||
(loop (deserialize-id))]
|
||||
[(identifier? deserialize-id)
|
||||
(let ([b (identifier-binding deserialize-id (variable-reference->phase varref))])
|
||||
(cons
|
||||
(and (list? b)
|
||||
(if (symbol? (caddr b))
|
||||
(caddr b)
|
||||
(protect-path
|
||||
(collapse/resolve-module-path-index
|
||||
(caddr b)
|
||||
(build-path (serialize-info-dir info)
|
||||
"here.ss"))
|
||||
rel-to)))
|
||||
(syntax-e deserialize-id)))]
|
||||
[(symbol? deserialize-id)
|
||||
(cons #f deserialize-id)]
|
||||
[else
|
||||
(cons
|
||||
(if (symbol? (cdr deserialize-id))
|
||||
(cdr deserialize-id)
|
||||
(protect-path
|
||||
(collapse/resolve-module-path-index
|
||||
(cdr deserialize-id)
|
||||
(build-path (serialize-info-dir info)
|
||||
"here.ss"))
|
||||
rel-to))
|
||||
(car deserialize-id))]))])
|
||||
(hash-ref
|
||||
mod-map path+name
|
||||
(lambda ()
|
||||
(let ([id (hash-count mod-map)])
|
||||
(hash-set! mod-map path+name id)
|
||||
id)))))
|
||||
(hash-set! cache deserialize-id id)
|
||||
id))))
|
||||
|
||||
(define (is-mutable? o)
|
||||
(or (and (or (mpair? o)
|
||||
|
|
Loading…
Reference in New Issue
Block a user