Changes -> and -! to %-> and %-!, because of too many name clashes in racket for ->.
This commit is contained in:
@@ -14,13 +14,13 @@
|
||||
|
||||
@defmodule[roos/class]
|
||||
|
||||
This module provides a compatibility layer between the @seclink["roos" #:doc '(lib "roos/scribblings/roos.scrbl") ]{@racketmodname[roos]} object system and the standard @racketmodname[racket/class] system. It exports the macros @racket[send], @racket[->], and @racket[new], which automatically dispatch to the appropriate implementation based on the type of the given object or class.
|
||||
This module provides a compatibility layer between the @seclink["roos" #:doc '(lib "roos/scribblings/roos.scrbl") ]{@racketmodname[roos]} object system and the standard @racketmodname[racket/class] system. It exports the macros @racket[send], @racket[%->], and @racket[new], which automatically dispatch to the appropriate implementation based on the type of the given object or class.
|
||||
|
||||
@section{Macros}
|
||||
|
||||
@defidform[send]{(send obj method arg ...)
|
||||
A generic message-send macro that works for both Roos objects and standard Racket class objects.
|
||||
If @racket[obj] is a Roos object (@racket[roos-object?]), it uses the Roos dispatch (@racket[->]).
|
||||
If @racket[obj] is a Roos object (@racket[roos-object?]), it uses the Roos dispatch (@racket[%->]).
|
||||
Otherwise, it falls back to the original @racket[send] from @racket[racket/class].}
|
||||
|
||||
@examples[
|
||||
@@ -32,7 +32,7 @@ Otherwise, it falls back to the original @racket[send] from @racket[racket/class
|
||||
(send o f 2) ; → 10
|
||||
]
|
||||
|
||||
@defidform[->]{(-> obj method arg ...)
|
||||
@defidform[%->]{(%-> obj method arg ...)
|
||||
An alternative method dispatch macro. The syntax omits the explicit @racket[send] and may feel more
|
||||
familiar to users of other programming languages that use concise or operator-based method invocation.
|
||||
This macro checks whether @racket[obj] is a Roos object or a standard Racket object and dispatches accordingly.}
|
||||
@@ -43,7 +43,7 @@ This macro checks whether @racket[obj] is a Roos object or a standard Racket obj
|
||||
(y x)
|
||||
((f a) (* a x)))
|
||||
(define o (new t 5))
|
||||
(-> o f 3) ; → 15
|
||||
(%-> o f 3) ; → 15
|
||||
]
|
||||
|
||||
@subsection{Comparison with other languages}
|
||||
@@ -56,7 +56,7 @@ In other languages, method invocation often uses compact notation:
|
||||
@item{C++: @tt{obj->method(args)} or @tt{obj.method(args)}}
|
||||
]
|
||||
|
||||
The @racket[->] macro serves a similar role within the s-expression syntax of Racket.
|
||||
The @racket[%->] macro serves a similar role within the s-expression syntax of Racket.
|
||||
|
||||
@defidform[new]{(new class arg ...)
|
||||
Creates a new object. If @racket[class] is a Roos class (@racket[roos-class?]), then @racket[roos-new] is used.
|
||||
@@ -77,7 +77,7 @@ Otherwise, the standard @racket[new] from @racket[racket/class] is used, support
|
||||
|
||||
(def-roos (t x) this (supers)
|
||||
(y x)
|
||||
((f a) (* (-> this y) a))
|
||||
((f a) (* (%-> this y) a))
|
||||
)
|
||||
|
||||
(displayln
|
||||
@@ -88,11 +88,11 @@ Otherwise, the standard @racket[new] from @racket[racket/class] is used, support
|
||||
(displayln
|
||||
(let ((cl (t% 6)))
|
||||
(let ((o (new cl)))
|
||||
(= (-> o f 3) 18))))
|
||||
(= (%-> o f 3) 18))))
|
||||
|
||||
(displayln
|
||||
(let ((o (new t 8)))
|
||||
(= (-> o f 4) 32)))
|
||||
(= (%-> o f 4) 32)))
|
||||
|
||||
(displayln
|
||||
(= (send (new t 4) f 2) 8))
|
||||
@@ -101,7 +101,7 @@ Otherwise, the standard @racket[new] from @racket[racket/class] is used, support
|
||||
@section{Implementation Notes}
|
||||
|
||||
@itemlist[
|
||||
@item{The original Racket @racket[send] and @racket[->] are renamed to @racket[old-send] and @racket[old->] internally.}
|
||||
@item{The original Racket @racket[send] and @racket[%->] are renamed to @racket[old-send] and @racket[old->] internally.}
|
||||
@item{The Roos-aware macros detect the object or class type and route to the correct implementation.}
|
||||
@item{@racket[new*] is a helper macro that transforms arguments into @racket[(v x)] form when needed.}
|
||||
]
|
||||
@@ -109,7 +109,7 @@ Otherwise, the standard @racket[new] from @racket[racket/class] is used, support
|
||||
@section{Testing}
|
||||
|
||||
The module includes an internal test suite using RackUnit.
|
||||
It validates consistent behavior of @racket[send], @racket[->], and @racket[new] across both Racket classes and Roos classes.
|
||||
It validates consistent behavior of @racket[send], @racket[%->], and @racket[new] across both Racket classes and Roos classes.
|
||||
|
||||
|
||||
@; End of documentation
|
||||
|
||||
@@ -49,10 +49,10 @@ Methods and fields are always virtual. Superclass definitions are resolved based
|
||||
@section{Object and Method Use}
|
||||
|
||||
@itemlist[
|
||||
@item{@racket[(-> obj field)] — call getter for field.}
|
||||
@item{@racket[(-> obj field! val)] — set field.}
|
||||
@item{@racket[(-> obj method args ...)] — invoke method.}
|
||||
@item{@racket[(->> obj name)] — retrieve method/field procedure.}
|
||||
@item{@racket[(%-> obj field)] — call getter for field.}
|
||||
@item{@racket[(%-> obj field! val)] — set field.}
|
||||
@item{@racket[(%-> obj method args ...)] — invoke method.}
|
||||
@item{@racket[(%->> obj name)] — retrieve method/field procedure.}
|
||||
@item{@racket[(roos-object? x)] — is it a ROOS object?}
|
||||
@item{@racket[(roos-class? x)] — is it a ROOS class definition?}
|
||||
@item{@racket[(roos-classname obj)] — symbolic class name.}
|
||||
@@ -63,11 +63,11 @@ Methods and fields are always virtual. Superclass definitions are resolved based
|
||||
|
||||
@subsection{Provided procedures}
|
||||
|
||||
@defproc[(-> [obj any/c] [name symbol?] ...) any/c]{
|
||||
@defproc[(%-> [obj any/c] [name symbol?] ...) any/c]{
|
||||
Invoke a getter, setter, or method on ROOS object @racket[obj] using name and arguments.
|
||||
}
|
||||
|
||||
@defproc[(->> [obj any/c] [name symbol?]) procedure?]{
|
||||
@defproc[(%->> [obj any/c] [name symbol?]) procedure?]{
|
||||
Return the method or field procedure named @racket[name] from object @racket[obj].
|
||||
Useful for higher-order usage.
|
||||
}
|
||||
@@ -105,7 +105,7 @@ Constructs a new ROOS object of the given @racket[class], optionally with argume
|
||||
If the class defines @racket[init], that method is invoked automatically.
|
||||
}
|
||||
|
||||
@defproc[(-! [class any/c] [args any/c] ...) any/c]{
|
||||
@defproc[(%-! [class any/c] [args any/c] ...) any/c]{
|
||||
Convenient shorthand for @racket[roos-new]. Also invokes @racket[init] if present.
|
||||
}
|
||||
|
||||
@@ -236,12 +236,12 @@ This example builds an address book with persistent reference to persons, using
|
||||
|
||||
((add p)
|
||||
(set! persons (vector-extend persons (+ (vector-length persons) 1) p))
|
||||
(-> this ids! (vector->list (vector-map (lambda (o) (-> o roos-id)) persons))))
|
||||
(%-> this ids! (vector->list (vector-map (lambda (o) (%-> o roos-id)) persons))))
|
||||
|
||||
((remove i)
|
||||
(set! persons (vector-append (vector-take persons i) (vector-drop persons (+ i 1))))
|
||||
(-> this ids! (vector->list
|
||||
(vector-map (lambda (o) (-> o roos-id)) persons))))
|
||||
(%-> this ids! (vector->list
|
||||
(vector-map (lambda (o) (%-> o roos-id)) persons))))
|
||||
|
||||
((for-each f)
|
||||
(letrec ((g (lambda (i n)
|
||||
@@ -251,34 +251,34 @@ This example builds an address book with persistent reference to persons, using
|
||||
(g 0 (vector-length persons))))
|
||||
|
||||
(init (begin
|
||||
(-> this roos-id! 'book)
|
||||
(%-> this roos-id! 'book)
|
||||
(let ((ps (map (lambda (id)
|
||||
(let ((p (roos-new person)))
|
||||
(-> p roos-id! id)
|
||||
(%-> p roos-id! id)
|
||||
p))
|
||||
(-> this ids))))
|
||||
(%-> this ids))))
|
||||
(set! persons (list->vector ps)))))
|
||||
)
|
||||
|
||||
;; Create sample data
|
||||
(define b (-! book))
|
||||
(define b (%-! book))
|
||||
|
||||
(define (adder n t)
|
||||
(let ((p (-! person)))
|
||||
(-> p name! n)
|
||||
(-> p tel! t)
|
||||
(-> b add p)))
|
||||
(let ((p (%-! person)))
|
||||
(%-> p name! n)
|
||||
(%-> p tel! t)
|
||||
(%-> b add p)))
|
||||
|
||||
(adder "Alice" "123")
|
||||
(adder "Bob" "456")
|
||||
(adder "Jos" "982")
|
||||
(adder "Rebecca" "363")
|
||||
|
||||
(-> b (for-each (lambda (p) (displayln (-> p name)))))
|
||||
(%-> b (for-each (lambda (p) (displayln (%-> p name)))))
|
||||
|
||||
;; Reopen addressbook later from persistent storage
|
||||
(define a (-! book))
|
||||
(-> b (for-each (lambda (p) (displayln (-> p name)))))
|
||||
(define a (%-! book))
|
||||
(%-> b (for-each (lambda (p) (displayln (%-> p name)))))
|
||||
|
||||
]
|
||||
|
||||
@@ -295,14 +295,14 @@ For example, a doubly-linked list:
|
||||
(next #f)
|
||||
(prev #f))
|
||||
|
||||
(define a (-! node))
|
||||
(-> a val! 1)
|
||||
(define a (%-! node))
|
||||
(%-> a val! 1)
|
||||
|
||||
(define b (-! node))
|
||||
(-> b val! 2)
|
||||
(define b (%-! node))
|
||||
(%-> b val! 2)
|
||||
|
||||
(-> a next! b)
|
||||
(-> b prev! a)
|
||||
(%-> a next! b)
|
||||
(%-> b prev! a)
|
||||
]
|
||||
|
||||
To avoid resource leaks when such cyclic structures are finalized, make sure that any cleanup (e.g. persistence flush) is done in @racket[finalize] methods. Racket's garbage collector can collect cyclic references if there are no external references left.
|
||||
|
||||
Reference in New Issue
Block a user