reference: further corrections to the surrogate docs

This commit is contained in:
Matthew Flatt 2018-06-19 19:54:19 -06:00
parent b7cb35fd66
commit 0b71883833

View File

@ -17,23 +17,17 @@ surrogate.
(surrogate use-wrapper-proc method-spec ...) (surrogate use-wrapper-proc method-spec ...)
([use-wrapper-proc #:use-wrapper-proc (code:line)] ([use-wrapper-proc #:use-wrapper-proc (code:line)]
[method-spec (augment default-expr method-id arg-spec ...) [method-spec (augment default-expr method-id arg-spec ...)
(override method-id arg-spec ...) (override method-id arg-spec ...)]
(override-final method-id (lambda () default-expr)
arg-spec ...)]
[arg-spec (id ...) [arg-spec (id ...)
id])]{ id])]{
If neither @racket[override] nor @racket[override-final] is specified The @racket[surrogate] form produces four values: a host @tech{mixin} (a
for a @racket[method-id], then @racket[override] is assumed. procedure that accepts and returns a class), a host @tech{interface}, a
surrogate @tech{class}, and a surrogate @tech{interface}.
The @racket[surrogate] form produces four values: a host mixin (a
procedure that accepts and returns a class), a host interface, a
surrogate class, and a surrogate interface.
If @racket[#:use-wrapper-proc] does not appear, If @racket[#:use-wrapper-proc] does not appear,
the host mixin adds one field @racket[surrogate] the host mixin adds a single private field to its argument. It also adds getter and setter methods
to its argument. It also adds getter and setter methods @racket[get-surrogate] and @racket[set-surrogate] to get and set the value of the field. The
@racket[get-surrogate] and @racket[set-surrogate]. The
@racket[set-surrogate] method accepts instances of the class returned by @racket[set-surrogate] method accepts instances of the class returned by
the @racket[surrogate] form or @racket[#f], and it updates the field with its the @racket[surrogate] form or @racket[#f], and it updates the field with its
argument; then, @racket[set-surrogate] calls the @racket[on-disable-surrogate] on the argument; then, @racket[set-surrogate] calls the @racket[on-disable-surrogate] on the
@ -42,21 +36,21 @@ new value of the field. The @racket[get-surrogate] method returns the
current value of the field. current value of the field.
If @racket[#:use-wrapper-proc] does appear, the the host mixin adds If @racket[#:use-wrapper-proc] does appear, the the host mixin adds
both the @racket[_surrogate] field (with its getters and setters) and a and a second private field and its getter and setter
a second field, @racket[_surrogate-wrapper-proc] and its getter and setter methods @racket[get-surrogate-wrapper-proc] and @racket[set-surrogate-wrapper-proc].
methods, @racket[_get-surrogate-wrapper-proc] and @racket[_set-surrogate-wrapper-proc]. The additional field holds a wrapper procedure whose contract
The @racket[_surrogate-wrapper-proc] field holds a procedure whose contract is @racket[(-> (-> any) (-> any) any)], so the procedure is invoked with two thunks.
is @racket[(-> (-> any) (-> any) any)]. The function is invoked with two thunks. The first thunk is a fallback that invokes the original object's method,
The first one is a fallback that invokes the original object's method, skipping the surrogate. The second thunk invokes the surrogate. The default
skipping the surrogate. The other one invokes the surrogate. wrapper procedure is
@racketblock[(λ (fallback-thunk surrogate-thunk) @racketblock[(λ (fallback-thunk surrogate-thunk)
(surrogate-thunk))] (surrogate-thunk))]
This means that it simply defers to the method being invoked on the surrogate. That is, it simply defers to the method being invoked on the surrogate.
The @racket[_surrogate-wrapper-proc] capability is part of the surrogate Note that wrapper procedure can adjust the
so that the dynamic extent of the calls to the surrogate can be adjusted dynamic extent of calls to the surrogate
(by, for example, changing the values of parameters). The by, for example, changing the values of parameters. The
@racket[_surrogate-wrapper-proc] is also invoked when calling the wrapper procedure is also invoked when calling the
@racket[_on-disable-surrogate] and @racket[_on-enable-surrogate] methods @racket[on-disable-surrogate] and @racket[on-enable-surrogate] methods
of the surrogate. of the surrogate.
The host mixin has a single overriding method for each The host mixin has a single overriding method for each
@ -65,9 +59,9 @@ specified with @racket[augment]). Each of these
methods is defined with a @racket[case-lambda] with one arm for each methods is defined with a @racket[case-lambda] with one arm for each
@racket[arg-spec]. Each arm has the variables as arguments in the @racket[arg-spec]. Each arm has the variables as arguments in the
@racket[arg-spec]. The body of each method tests the @racket[arg-spec]. The body of each method tests the
@racket[surrogate] field. If it is @racket[#f], the method just private surrogate field. If the field value is @racket[#f], the method just
returns the result of invoking the super or inner method. If the returns the result of invoking the super or inner method. If the
@racket[surrogate] field is not @racket[#f], the corresponding method field value is not @racket[#f], the corresponding method
of the object in the field is invoked. This method receives the same of the object in the field is invoked. This method receives the same
arguments as the original method, plus two extras. The extra arguments arguments as the original method, plus two extras. The extra arguments
come at the beginning of the argument list. The first is the original come at the beginning of the argument list. The first is the original
@ -87,7 +81,7 @@ will override the @racket[m] method and call the surrogate like this:
x y z) x y z)
(super m x y z)))] (super m x y z)))]
where @racket[_surrogate] is bound to the value most recently passed where @racket[_surrogate] is bound to the value most recently passed
to the host mixin's @racket[_set-surrogate] method. to the host mixin's @racket[set-surrogate] method.
The host interface has the names @racket[set-surrogate], The host interface has the names @racket[set-surrogate],
@racket[get-surrogate], and each of the @racket[method-id]s in the @racket[get-surrogate], and each of the @racket[method-id]s in the
@ -103,7 +97,7 @@ In the example above, this is the @racket[_m] method in the surrogate class:
@racketblock[(define/public (m original-object original-super x y z) @racketblock[(define/public (m original-object original-super x y z)
(original-super x y z))] (original-super x y z))]
Note: if you derive a class from the surrogate class, do not both call If you derive a class from the surrogate class, do not both call
the @racket[super] argument and the super method of the surrogate the @racket[super] argument and the super method of the surrogate
class itself. Only call one or the other, since the default methods class itself. Only call one or the other, since the default methods
call the @racket[super] argument. call the @racket[super] argument.