diff --git a/pkgs/racket-doc/scribblings/reference/serialization.scrbl b/pkgs/racket-doc/scribblings/reference/serialization.scrbl index 74a7dea586..b5e29d067e 100644 --- a/pkgs/racket-doc/scribblings/reference/serialization.scrbl +++ b/pkgs/racket-doc/scribblings/reference/serialization.scrbl @@ -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 diff --git a/pkgs/racket-test-core/tests/racket/serialize.rktl b/pkgs/racket-test-core/tests/racket/serialize.rktl index eec585a40d..7630d98de6 100644 --- a/pkgs/racket-test-core/tests/racket/serialize.rktl +++ b/pkgs/racket-test-core/tests/racket/serialize.rktl @@ -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) diff --git a/racket/collects/racket/private/serialize.rkt b/racket/collects/racket/private/serialize.rkt index 93b4688bf2..1bad079d5d 100644 --- a/racket/collects/racket/private/serialize.rkt +++ b/racket/collects/racket/private/serialize.rkt @@ -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)