diff options
-rw-r--r-- | doc/ref/goops-tutorial.texi | 61 | ||||
-rw-r--r-- | doc/ref/goops.texi | 150 |
2 files changed, 71 insertions, 140 deletions
diff --git a/doc/ref/goops-tutorial.texi b/doc/ref/goops-tutorial.texi index 76774f8d1..28ab86875 100644 --- a/doc/ref/goops-tutorial.texi +++ b/doc/ref/goops-tutorial.texi @@ -30,21 +30,13 @@ @c Guile @c @end macro -This section introduces the @goops{} package in more detail. It was -originally written by Erick Gallesio as an appendix for the STk -reference manual, and subsequently adapted to @goops{}. - -The procedures and syntax described in this tutorial are provided by -Guile modules that may need to be imported before being available. -The main @goops{} module is imported by evaluating: +To start using @goops{} you first need to import the @code{(oop goops)} +module. You can do this at the Guile REPL by evaluating: @lisp (use-modules (oop goops)) @end lisp @findex (oop goops) -@cindex main module -@cindex loading -@cindex preparing @menu * Class definition:: @@ -68,13 +60,16 @@ of @code{define-class} is close to CLOS @code{defclass}: @var{class-option} @dots{}) @end lisp -@var{class} is the class being defined. The list of -@var{superclass}es specifies which existing classes, if any, to -inherit slots and properties from. Each @var{slot-description} gives -the name of a slot and optionally some ``properties'' of this slot; -for example its initial value, the name of a function which will -access its value, and so on. Slot descriptions and inheritance are -discussed more below. For class options, see @ref{Class Options}. +@var{class} is the class being defined. The list of @var{superclass}es +specifies which existing classes, if any, to inherit slots and +properties from. @dfn{Slots} hold per-instance@footnote{Usually --- but +see also the @code{#:allocation} slot option.} data, for instances of +that class --- like ``fields'' or ``member variables'' in other object +oriented systems. Each @var{slot-description} gives the name of a slot +and optionally some ``properties'' of this slot; for example its initial +value, the name of a function which will access its value, and so on. +Slot descriptions and inheritance are discussed more below. For class +options, see @ref{Class Options}. @cindex slot As an example, let us define a type for representing a complex number @@ -556,6 +551,38 @@ However, this result is not too much readable; using the function @node Generic functions @subsection Generic functions +A GOOPS method is like a Scheme procedure except that it is specialized +for a particular set of argument classes, and will only be used when the +actual arguments in a call match the classes in the method definition. + +@lisp +(define-method (+ (x <string>) (y <string>)) + (string-append x y)) + +(+ "abc" "de") @result{} "abcde" +@end lisp + +A method is not formally associated with any single class (as it is in +many other object oriented languages), because a method can be +specialized for a combination of several classes. If you've studied +object orientation in non-Lispy languages, you may remember discussions +such as whether a method to stretch a graphical image around a surface +should be a method of the image class, with a surface as a parameter, or +a method of the surface class, with an image as a parameter. In GOOPS +you'd just write + +@lisp +(define-method (stretch (im <image>) (sf <surface>)) + ...) +@end lisp + +@noindent +and the question of which class the method is more associated with does +not need answering. + +A generic function is a collection of methods with the same name but +different sets of specializing argument classes. + @menu * Generic functions and methods:: * Next-method:: diff --git a/doc/ref/goops.texi b/doc/ref/goops.texi index 9344e6793..a0494db52 100644 --- a/doc/ref/goops.texi +++ b/doc/ref/goops.texi @@ -30,7 +30,6 @@ overriding or redefining those methods. @menu * Copyright Notice:: -* Quick Start:: * Tutorial:: * Defining New Classes:: * Creating Instances:: @@ -68,128 +67,6 @@ The material has been adapted for use in Guile, with the author's permission. -@node Quick Start -@section Quick Start - -To start using GOOPS, load the @code{(oop goops)} module: - -@lisp -(use-modules (oop goops)) -@end lisp - -We're now ready to try some basic GOOPS functionality. - -@menu -* Methods:: -* Built-in classes:: -* User-defined classes:: -@end menu - - -@node Methods -@subsection Methods - -A GOOPS method is like a Scheme procedure except that it is -specialized for a particular set of argument classes. - -@lisp -(define-method (+ (x <string>) (y <string>)) - (string-append x y)) - -(+ "abc" "de") @result{} "abcde" -@end lisp - -If @code{+} is used with arguments that do not match the method's -classes, Guile falls back to using the normal Scheme @code{+} procedure. - -@lisp -(+ 1 2) @result{} 3 -@end lisp - - -@node Built-in classes -@subsection Built-in classes - -There are built-in classes like @code{<string>}, @code{<list>} and -@code{<number>} corresponding to all the Guile Scheme types. You can -use the @code{is-a?} predicate to ask whether any given value belongs to -a given class, or @code{class-of} to discover the class of a given -value. - -@lisp -(is-a? 2.3 <number>) @result{} #t -(is-a? 2.3 <real>) @result{} #t -(is-a? 2.3 <string>) @result{} #f -(is-a? '("a" "b") <string>) @result{} #f -(is-a? '("a" "b") <list>) @result{} #t -(is-a? (car '("a" "b")) <string>) @result{} #t -(is-a? <string> <class>) @result{} #t -(is-a? <class> <string>) @result{} #f - -(class-of 2.3) @result{} #<<class> <real> 908c708> -(class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20> -(class-of <string>) @result{} #<<class> <class> 8bd3e10> -(class-of <class>) @result{} #<<class> <class> 8bd3e10> -@end lisp - - -@node User-defined classes -@subsection User-defined classes - -You can, of course, also define new classes. The GOOPS term for -``fields'' or ``member variables'' is @dfn{slots}, and the main thing -you have to specify, when defining a new class, is what its slots will -be, and how they will be initialised and accessed. - -@lisp -(define-class <2D-vector> () - (x #:init-value 0 #:accessor x-component #:init-keyword #:x) - (y #:init-value 0 #:accessor y-component #:init-keyword #:y)) -@end lisp - -Methods are not formally part of a specific class's definition, -because a single method can be associated with several classes. If -you've studied object orientation in non-Lispy languages, you may -remember discussions such as whether a method to stretch a graphical -image around a surface should be a method of the image class, with a -surface as a parameter, or a method of the surface class, with an image -as a parameter. In the generic function approach that GOOPS provides, -this question does not arise. - -Here we customise @code{write} for the new class, so that -@code{<2D-vector>} objects will be nicely printed: - -@lisp -(use-modules (ice-9 format)) - -(define-method (write (obj <2D-vector>) port) - (format port "<~S, ~S>" (x-component obj) (y-component obj))) -@end lisp - -To make an @dfn{instance} or @dfn{object} of your new class, use -@code{make} together with the class and any initialisation arguments: - -@lisp -(define v (make <2D-vector> #:x 3 #:y 4)) - -v @result{} <3, 4> -(is-a? v <2D-vector>) @result{} #t -(class-of v) @result{} #<<class> <2D-vector> 40241ac0> -@end lisp - -Here is another method that is specialised for @code{<2D-vector>} -objects, to add two of them together: - -@lisp -(define-method (+ (x <2D-vector>) (y <2D-vector>)) - (make <2D-vector> - #:x (+ (x-component x) (x-component y)) - #:y (+ (y-component x) (y-component y)))) - -(+ v v) @result{} <6, 8> -@end lisp - - @node Tutorial @section Tutorial @include goops-tutorial.texi @@ -1234,6 +1111,7 @@ GOOPS equivalents --- to be obtained dynamically, at run time. * Classes:: * Slots:: * Instances:: +* Built-in classes:: * Generic Functions:: * Generic Function Methods:: @end menu @@ -1400,6 +1278,32 @@ Implementation notes: @code{is-a?} uses @code{class-of} and @code{class-precedence-list} to obtain the class precedence list for @var{object}. +@node Built-in classes +@subsection Built-in classes + +There are built-in classes like @code{<string>}, @code{<list>} and +@code{<number>} corresponding to all the Guile Scheme types. You can +use the @code{is-a?} predicate to ask whether any given value belongs to +a given class, or @code{class-of} to discover the class of a given +value. + +@lisp +(is-a? 2.3 <number>) @result{} #t +(is-a? 2.3 <real>) @result{} #t +(is-a? 2.3 <string>) @result{} #f +(is-a? '("a" "b") <string>) @result{} #f +(is-a? '("a" "b") <list>) @result{} #t +(is-a? (car '("a" "b")) <string>) @result{} #t +(is-a? <string> <class>) @result{} #t +(is-a? <class> <string>) @result{} #f + +(class-of 2.3) @result{} #<<class> <real> 908c708> +(class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20> +(class-of <string>) @result{} #<<class> <class> 8bd3e10> +(class-of <class>) @result{} #<<class> <class> 8bd3e10> +@end lisp + + @node Generic Functions @subsection Generic Functions |