
1: @node Object system, Library modules - Overview, Core library, Top 2: @chapter Object system 3: @c NODE ???Ö¥??????È¥????Æ¥?@c EN 4: Gauche's object system design is largely inspired by 5: STklos, whose design has come from TinyCLOS. 6: It supports multiple inheritance, multimethods, 7: and metaobject protocol. 8: @c JP 9: Gauche?Î¥??Ö¥??????È¥????Æ¥??Ç¥??????TinyCLOS??????????STklos???????ʱƶ????Ƥ??Þ¤??? 10: ¿?ŷѾ????Þ¥??᥽?åɡ??᥿???Ö¥??????È¥×¥È¥í¥³?? 11: ???Ý¡??Ȥ??Ƥ??Þ¤??? 12: @c COMMON 13: 14: @c EN 15: The type system is integrated to the object system, 16: that is, a string is an instance of the class @code{<string>}, 17: and so on. 18: @c JP 19: ???????Æ¥??????Ö¥??????È¥????Æ¥???礵?????Þ¤??? 20: ?Ĥޤꡢʸ??@code{<string>}???饹?Î¥??ó¥¹¥??󥹤Ǥ??ë¡¢?ʤɤǤ??? 21: @c COMMON 22: 23: @c ---------------------------------------------------------------------- 24: @menu 25: * Introduction to the object system:: 26: * General Inquiry:: 27: * Class:: 28: * Instance:: 29: * Generic function and method:: 30: * Metaobject protocol:: 31: @end menu 32: 33: @node Introduction to the object system, General Inquiry, Object system, Object system 34: @section Introduction to the object system 35: @c NODE ???Ö¥??????È¥????Æ¥??Ò²?c EN 36: This section briefly explains the basic structure of 37: Gauche's object system. It is strongly influenced 38: by CLOS (Common-Lisp Object System). 39: If you have experience in CLOS or related systems 40: such as TinyCLOS, STklos or Guile's object system, 41: you may skip to the next section. 42: 43: Three concepts play the central role in CLOS-like object systems: 44: A @emph{class}, a @emph{generic function}, and a @emph{method}. 45: 46: A @emph{class} specifies a structure of object. 47: It also defines a datatype (strictly speaking, 48: it's not the same thing as a datatype, 49: but let's skip the complicated part for now). 50: 51: For example, a point in 2D space can be represented by 52: x and y coordinates. 53: A point class can be defined using @code{define-class} macro. 54: In the shortest form, it can be defined like this: 55: 56: @c JP 57: ???????Gauche ?Î¥??Ö¥??????È¥????Æ¥??????¤?ˤĤ??Ƽ??????????Þ¤???Gauche ?Î¥??Ö¥??????È¥????Æ¥? CLOS (Common-Listp Object System) 58: ?˶????ƶ???????Þ¤???CLOS ?䤽?????????Τ???inyCLOS??STklos?? 59: ???뤤??Guile ?Î¥??Ö¥??????È¥????Æ¥??и????????Ï¡????????Ф??Æ¡? 60: ????????äƤ????Ǥ??礦?? 61: 62: CLOS ??Î¥??Ö¥??????È¥????Æ¥???3 ?Ĥγ?ǰ?????Ū????????Þ¤??? 63: @emph{???饹}??@emph{?????Í¥????Ø¿?????@emph{?᥽?Ã¥??Ǥ??? 64: 65: @emph{???饹}?Ï¥??Ö¥??????Ȥι?¤??ꤷ?Þ¤????Þ¤????Ç¡???????????Þ¤? 66: (??Ì©?ˤ????È¡??Ç¡??????ȤϤ???????Ǥ???????????Ȥ????????????Ƥ????Þ¤??礦)?? 67: 68: ???Ȥ??С?2 ?????????x ?????y ?????????Ǥ??Þ¤?????Î¥??饹??@code{define-class} ?Þ¥????Ȥä???Ǥ??Þ¤??????Ȥ?û???ˤϡ? 69: ???Τ褦????Ǥ??Þ¤??? 70: 71: @c COMMON 72: @example 73: (define-class <2d-point> () (x y)) 74: @end example 75: 76: @c EN 77: (You can find the code of definitions in the examples of this section 78: in @code{examples/oointro.scm} of Gauche's source distribution.) 79: 80: The symbol @code{<2d-point>} is the name of the class, and also 81: the global variable @code{<2d-point>} is bound to a class object. 82: Surrounding a class name by @code{<} and @code{>} is just a 83: convention; you can pass any symbol to @code{define-class}. 84: 85: The second argument of @code{define-class} is a list of 86: direct superclasses, which specifies inheritance of the class. 87: We'll come back to it later. 88: 89: The third argument of @code{define-class} is a list of 90: @emph{slots}. A slot is a storage space, usually in each object, 91: where you can store a value. It is something similar to 92: what is called a field or an instance variable in other 93: object-oriented languages; but slots can be configured more 94: than just a per-object storage space. 95: 96: Now we defined a 2D point class, so we can create an instance 97: of a point. You can pass a class to a generic function @code{make} 98: to create an instance. (Don't worry about what generic function 99: is---think it as a special type of function, just for now). 100: 101: @c JP 102: (??????????????ɤ?Gauche ????????ʪ?Τʤ??? 103: @code{examples/oointro.scm} ?ˤ???????) 104: 105: ?????code{<2d-point>} ?Ï¥??饹?????Ǥ??????í¡¼?Ð¥???ode{<2d-point>}?Ï¥??饹???Ö¥??????Ȥ??????????Þ¤??????饹̾??ode{<} ??@code{>} ?ǰϤ??Ï´????ˤ????Þ¤???code{define-class} 106: ?ˤ???դΥ??????????Ȥ??Ǥ??Þ¤??? 107: 108: @code{define-class}???????ľ??Î¥????Ñ¡????饹?Υꥹ?ȤǤ??? 109: ???????Î¥??饹?ηѾ???ꤷ?Þ¤????????Ĥ??Ƥϸ??????Þ¤??? 110: 111: @code{define-class}??è»°??@emph{???????Υꥹ?ȤǤ??? 112: ?????ȤϤʤˤ???????Ƥ??????Ç¡?????Æ¥??Ö¥??????Ȥ?Ф??Æ¡??????Ǥ??Þ¤??? 113: ??????¾?Î¥????????Ȼظ?????Ï¡??Õ¥??????Ȥ????ó¥¹¥???Ñ¿?ɤ??ƤФ??????Τ˻÷¤¿¤??Ǥ????????????????Ȥ???ʤ????Ö¥???????? 114: ??????Ú¡????ʾ??Ȥ?????Ǥ??Þ¤??? 115: 116: ???Æ¡?2 ???????Î¥??饹?????Þ¤????Τǡ???Î¥??ó¥¹¥??󥹤???Ǥ??Þ¤??? 117: ???饹?ò¥¸¥??Í¥????Ø¿?ode{make} ??Ϥ??Æ¥??ó¥¹¥??󥹤?????Þ¤??? 118: (?????Í¥????Ø¿ô¤¬¤É¤???Ǥ??뤫?ϵ??ˤ??ʤ??Dz??????????Ϥ????? 119: ?????פδؿ????ͤ??Ƥ????Ƥ????????) 120: 121: @c COMMON 122: @example 123: (define a-point (make <2d-point>)) 124: 125: a-point @result{} #<<2d-point> 0x8117570> 126: @end example 127: 128: @c EN 129: If you are using @code{gosh} interactively, you can use 130: a generic function @code{describe} to inspect the internal 131: of an instance. 132: A short alias, @code{d}, is defined to @code{describe} for 133: the convenience. (See @ref{Interactive session} 134: for the details). 135: 136: @c JP 137: ???⡼?ɤ?@code{gosh} ??äƤ????é¡¢?????Í¥????Ø¿?ode{describe} ???äơ????ó¥¹¥??󥹤??????Ǥ??Þ¤??? 138: ???ʤΤǡ??????Ȥ???code{d}?Ȥ???̾???????????Þ¤??? 139: (?ܺ٤ˤĤ??Ƥϡ?@ref{Interactive session}???? 140: 141: @c COMMON 142: @example 143: gosh> (d a-point) 144: #<<2d-point> 0x8117570> is an instance of class <2d-point> 145: slots: 146: x : #<unbound> 147: y : #<unbound> 148: @end example 149: 150: @c EN 151: In order to access or modify the value of the slot, you can use 152: @code{slot-ref} and @code{slot-set!}, respectively. 153: These names are taken from STklos. 154: 155: @example 156: (slot-ref a-point 'x) ;; access to the slot x of a-point 157: @result{} @r{error, since slot 'x doesn't have a value yet} 158: 159: (slot-set! a-point 'x 10.0) ;; set 10.0 to the slot x of a-point 160: 161: (slot-ref a-point 'x) 162: @result{} 10.0 163: @end example 164: 165: @c JP 166: ?????Ȥ?ͤ˥??????????뤤??ͤ?????뤿???Ï¡????줾?ì¡¢ 167: @code{slot-ref} ???? @code{slot-set!} ???Ȥ??Þ¤?????????????STklos ???????????? 168: 169: @example 170: (slot-ref a-point 'x) ;; a-point ?Î¥?????x ?Ë¥??????? 171: @result{} @r{error, since slot 'x doesn't have a value yet} 172: 173: (slot-set! a-point 'x 10.0) ;; a-point ?Î¥?????x ??.0 ????(slot-ref a-point 'x) 174: @result{} 10.0 175: @end example 176: 177: @c EN 178: Gauche also provides a shorter name, @code{ref}, which can also 179: be used in srfi-17's generalized @code{set!} syntax: 180: @c JP 181: Gauche ?Ǥϡ???û????̾? @code{ref} ?????Þ¤????????Ȥ???srfi-17 ?ΰ??????줿 @code{set!} ?ι?ʸ???Ȥ??Þ¤??? 182: @c COMMON 183: @example 184: (ref a-point 'x) @result{} 10.0 185: 186: (set! (ref a-point 'y) 20.0) 187: 188: (ref a-point 'y) @result{} 20.0 189: @end example 190: 191: @c EN 192: Now you can see slot values are set. 193: @c JP 194: ?????Ȥ?ͤ??????????뤳?Ȥò¸«¤Æ¤ß¤Þ¤??礦?? 195: @c COMMON 196: @example 197: gosh> (d a-point) 198: #<<2d-point> 0x8117570> is an instance of class <2d-point> 199: slots: 200: x : 10.0 201: y : 20.0 202: @end example 203: 204: @c EN 205: In practice, it is usually convenient if you can specify the default 206: value for a slot, or give values for slots when you create an instance. 207: Such information can be specified by @emph{slot options}. 208: Let's modify the definition of @code{<2d-point>} like this: 209: 210: @c JP 211: ?ºݤˤϡ??????Ȥ˥ǥե????????????ê¡¢???ó¥¹¥??????????????Ȥ?ͤ?????????ʤ??Ȥ?¿???Ǥ??????Τ褦?ʾ?Ï¡? 212: @emph{?????È¥??×¥???}?Ç»?????Þ¤???@code{<2d-point>}??????Τ褦??ѹ????Ƥߤޤ??礦?? 213: 214: @c COMMON 215: @example 216: (define-class <2d-point> () 217: ((x :init-value 0.0 :init-keyword :x :accessor x-of) 218: (y :init-value 0.0 :init-keyword :y :accessor y-of))) 219: @end example 220: 221: @c EN 222: Note that each slot specification is now a list, instead of just 223: a symbol as in the previous example. 224: The list's car now specifies the slot name, and its cdr 225: gives various information. The value after @code{:init-value} 226: defines the default value of the slot. The keyword after @code{:init-keyword} 227: defines the keyword argument which can be passed to @code{make} to 228: initialize the slot at creation time. 229: The name after keyword @code{:accessor} is bound to a generic 230: function that can be used to access/modify the slot, instead of 231: using @code{slot-ref}/@code{slot-set!}. 232: 233: Let's see some interactive session. You create an instance 234: of the new @code{<2d-point>} class, and you can see the slots are 235: initialized by the default values. 236: @c JP 237: ?Æ¥????Ȥλ?????????ϰ??Î¥????????????????ϥꥹ???Ǥ??뤳?Ȥ?????Ƥ???????? 238: ????Ï¡??ꥹ?Ȥ?car ?ʬ??????????λ????cdr ?ʬ?ˤ??í¤¤????? 239: ?Ϥ???????@code{:init-value} ?Τ???????Ϥ??Î¥????ȤΥǥե??????????Ƥ??Þ¤???@code{:init-keyword}?Τ???????????ɤϡ??????Ë¥????Ȥ??ü²½¤¹¤ë¤¿?? @code{make} ??Ϥ????ȤΤǤ??ë¥????ɰ??????Ƥ??Þ¤??? 240: ???????@code{:accessor} ?Τ?????̾??Ï¡??????ȤؤΥ???????/??????????Ȥ??른???Í¥????Ø¿??????????????? 241: @code{slot-ref}/@code{slot-set!} ?Τ????˻Ȥ??Þ¤??? 242: 243: ????Ȥ????????Ã¥?????Ƥߤޤ??礦???????? @code{<2d-point>} ???饹?????ó¥¹¥??󥹤?????????????Ȥ??Ç¥Õ¥?????ǽ??????????????狼??Þ¤??Í¡? 244: @c COMMON 245: @example 246: gosh> (define a-point (make <2d-point>)) 247: a-point 248: gosh> (d a-point) 249: #<<2d-point> 0x8148680> is an instance of class <2d-point> 250: slots: 251: x : 0.0 252: y : 0.0 253: @end example 254: 255: @c EN 256: You create another instance, this time giving initialization values 257: by keyword arguments. 258: @c JP 259: ????Ï¡???????ɰ????????Æ¡???Î¥??ó¥¹¥??󥹤?????? 260: @c COMMON 261: @example 262: gosh> (define b-point (make <2d-point> :x 50.0 :y -10.0)) 263: b-point 264: gosh> (d b-point) 265: #<<2d-point> 0x8155b80> is an instance of class <2d-point> 266: slots: 267: x : 50.0 268: y : -10.0 269: @end example 270: 271: @c EN 272: Accessors are less verbose than @code{slot-ref}/@code{slot-set!}, thus 273: convenient. 274: @c JP 275: ??????????@code{slot-ref}/@code{slot-set!} ??û?????ʤä???ʤ??????Í¡? 276: @c COMMON 277: @example 278: gosh> (x-of a-point) 279: 0.0 280: gosh> (x-of b-point) 281: 50.0 282: gosh> (set! (y-of a-point) 3.33) 283: #<undef> 284: gosh> (y-of a-point) 285: 3.33 286: @end example 287: 288: @c EN 289: The full list of available slot options is described in 290: @ref{Defining class}. At a first grance, 291: the declarations of such slot options may look verbose. 292: The system might have provide a static way to define 293: init-keywords or accessor names automatically; however, 294: CLOS-like systems prefer flexibility. 295: Using a mechanism called metaobject protocol, you can customize 296: how these slot options are interpreted, and you can add 297: your own slot options as well. 298: See @ref{Metaobject protocol}, for details. 299: 300: We can also have @code{<2d-vector>} class in similar fashion. 301: 302: @c JP 303: ?????????????È¥??×¥????Υꥹ?Ȥ?ref{Defining class}?ˤ??????? 304: ????ȸ??????????Î¥????È¥??×¥???????Ͼ??˸????뤫?⤷???????????Æ¥??ǽ?????????ɤ䥢??????̾???Ū???????Ū?Ê»?Ȥ??Õ¤??뤳?Ȥ????????⤷?????????????ʤ??é¡¢CLOS ??Î¥????Æ¥??Ͻ??????뤷?Þ¤??? 305: ?᥿???Ö¥??????È¥×¥??????ƤФ??????????Æ¡????????????È¥??×¥??????ɤΤ褦?˲???????ò¥«¥????Þ¥??????뤳?Ȥ??Ǥ??Þ¤??? 306: ?Þ¤?????ʬ??Î¥????È¥??×¥?????ä??뤳?Ȥ????Þ¤??? 307: ?ܤ?????@ref{Metaobject protocol} ?ò¸«¤Æ¤???????? 308: 309: ?Þ¤????÷¤¿¤è¤¦???????@code{<2d-vector>} ???饹???Ǥ??Þ¤??? 310: 311: @c COMMON 312: @example 313: (define-class <2d-vector> () 314: ((x :init-value 0.0 :init-keyword :x :accessor x-of) 315: (y :init-value 0.0 :init-keyword :y :accessor y-of))) 316: @end example 317: 318: @c EN 319: Yes, we can use the same accessor name like @code{x-of}, and 320: it is effectively overloaded. 321: 322: If you are familiar with mainstream object-oriented languages, 323: you may wonder where methods are. Here they are. 324: The following form defines a method @code{move-by!} of 325: three arguments, @var{pt}, @var{dx}, @var{dy}, where @var{pt} is 326: an instance of @code{<2d-point>}. 327: 328: @c JP 329: ?????Ǥ???Ʊ??????????̾??ode{x-of} ?Τ褦?˻Ȥ????Ȥ??Ǥ??Þ¤??? 330: ??????塢¿??????????? 331: 332: ???Î¥??Ö¥??????Ȼظ???????줿??Ï¡????í¤½?í¡¢?᥽?åɤϤɤ??ˤ???????פ??Ϥ????뤫?⤷?????󡣤??褤?????åɤ?о??????ʲ??Î¥Õ¥???????3 ?Ĥΰ?var{pt}??@var{dy}??@var{dy} ??ê¡¢ 333: ??????ar{pt} ??@code{<2d-point>} ?Î¥??ó¥¹¥??󥹤Ǥ????????᥽?Ã¥?@code{move-by!} ???????ΤǤ??? 334: 335: @c COMMON 336: @example 337: (define-method move-by! ((pt <2d-point>) dx dy) 338: (inc! (x-of pt) dx) 339: (inc! (y-of pt) dy)) 340: @end example 341: 342: @c EN 343: The second argument of @code{define-method} macro specifies a 344: @emph{method specializer list}. It indicates the first argument must be 345: an instance of @code{<2d-point>}, and the second and third 346: can be any type. The syntax to call a method is just like 347: the one to call an ordinary function. 348: 349: @c JP 350: @code{define-method} ?Þ¥???????@emph{?᥽?Ã¥??ê²½?ҥꥹ????????Ƥ??Þ¤??????????????@code{<2d-point>} ?Î¥??ó¥¹¥??󥹤??ʤ????ʤ??????Ȥò¼¨¤????????????Ǥ?դη??Ǥ褤???Ȥ????Ƥ??Þ¤????᥽?åɸƤӽФ??ι?ʸ??̾???ƤӽФ???????Ǥ??? 351: 352: @c COMMON 353: @example 354: gosh> (move-by! b-point 1.4 2.5) 355: #<undef> 356: gosh> (d b-point) 357: #<<2d-point> 0x8155b80> is an instance of class <2d-point> 358: slots: 359: x : 51.4 360: y : -7.5 361: @end example 362: 363: @c EN 364: You can overload the method by different specializers; here 365: you can move a point using a vector. 366: @c JP 367: ????ê²½?Ҥˤ????Υ᥽?åɤ??????뤳?Ȥ?????Ǥ????ʲ??Τ褦???Ù¥?????ä?????????Ȥ????Þ¤??? 368: @c COMMON 369: @example 370: (define-method move-by! ((pt <2d-point>) (delta <2d-vector>)) 371: (move-by! pt (x-of delta) (y-of delta))) 372: @end example 373: 374: @c EN 375: Specialization isn't limited to a user-defined classes. 376: You can also specialize a method using Gauche's built-in type. 377: @c JP 378: ?????ϥ桼?????Î¥??饹?ˤ????ꤵ?????????ǤϤ???????Gauche ??Ȥ߹??ß·???äƥ᥽?åɤ?ê²½???뤳?Ȥ????Þ¤??? 379: 380: @c COMMON 381: @example 382: (define-method move-by! ((pt <2d-point>) (c <complex>)) 383: (move-by! pt (real-part c) (imag-part c))) 384: @end example 385: 386: @c EN 387: And here's the example session: 388: @c JP 389: ?ʲ??Ï¥??Ã¥?????Ǥ??? 390: @c COMMON 391: @example 392: gosh> (define d-vector (make <2d-vector> :x -9.0 :y 7.25)) 393: d-vector 394: gosh> (move-by! b-point d-vector) 395: #<undef> 396: gosh> (d b-point) 397: #<<2d-point> 0x8155b80> is an instance of class <2d-point> 398: slots: 399: x : 42.4 400: y : -0.25 401: gosh> (move-by! b-point 3+2i) 402: #<undef> 403: gosh> (d b-point) 404: #<<2d-point> 0x8155b80> is an instance of class <2d-point> 405: slots: 406: x : 45.4 407: y : -2.25 408: @end example 409: 410: @c EN 411: You see that a method is dispatched not only by its primary 412: receiver (@code{<2d-point>}), but also other arguments. 413: In fact, the first argument is no more special than the rest. 414: In CLOS-like system a method does not belong to 415: a particular class. 416: 417: So what is actually a method? Inspecting @code{move-by!} 418: reveals that it is an instance of @code{<generic>}, a generic function. 419: (Note that @code{describe} truncates the printed value in @code{methods} 420: slot for the sake of readability). 421: @c JP 422: ?᥽?åɤ????μ???????@code{<2d-point>} ?ˤ??ƤΤߥǥ????ѥå???? 423: ?ΤǤϤʤ?????????ΰ????Ƥ??????ѥå???????????狼???פ??Þ¤??? 424: ?¤ϡ??????Ĥ?????٤Ʋ?????ǤϤ???????CLOS ??Î¥????Æ¥??ϥ᥽?åɤ??????饹????????ΤǤϤʤ??ΤǤ??? 425: 426: ?Ǥϥ᥽?åɤȤϤ??ä????ʤ???礦??@code{move-by!} ??????Ƥߤ? 427: ???줬 @code{<generic>} ?Î¥??ó¥¹¥??󥹤Ǥ??ê¡¢?????Í¥????Ø¿???? 428: ?狼??????(@code{describe} ?ϲ????Τ??? @code{methods} ?????Ȥ???ΰ?????äƤ??뤳?Ȥ?????Ƥ????????) 429: 430: @c COMMON 431: @example 432: gosh> move-by! 433: #<generic move-by! (3)> 434: gosh> (d move-by!) 435: #<generic move-by! (3)> is an instance of class <generic> 436: slots: 437: name : move-by! 438: methods : (#<method (move-by! <2d-point> <complex>)> #<method (move- 439: gosh> (ref move-by! 'methods) 440: (#<method (move-by! <2d-point> <complex>)> 441: #<method (move-by! <2d-point> <2d-vector>)> 442: #<method (move-by! <2d-point> <top> <top>)>) 443: @end example 444: 445: @c EN 446: I said a generic function is a special type of function. 447: It is recognized by Gauche as an applicable object, but 448: when applied, it selects appropriate method(s) according to 449: its arguments and calls the selected method(s). 450: 451: What the @code{define-method} macro actually does is (1) to create 452: a generic function of the given name if it does not exist yet, 453: (2) to create a method object with the given specializers 454: and the body, and (3) to add the method object to the generic function. 455: 456: The accessors are also generic functions, created implicitly by the 457: @code{define-class} macro. 458: @c JP 459: ?????Í¥????Ø¿??̤ʥ????פδؿ?ȸ???Þ¤???????Gauche ?ǤϤ??? 460: Ŭ???????Ö¥??????ȤȤ????????????????????Ŭ??????Ȥ??ΰ? 461: ??????????ʥ᥽?åɤ?ò¤·¤Æ¡??????????줿?᥽?åɤ?ӽФ??Ȥ???ư?? 462: ?Ô¤??Þ¤??? 463: 464: ?º?@code{define-method} ?Þ¥??í¤¬???Ƥ??뤳?Ȥϡ?(1)?⤷Ϳ?????? 465: ̾??Î¥????Í¥????Ø¿ô¤¬¤Þ¤???ߤ??Ƥ??ʤ???????????????(2)Í¿?????? 466: ?????Ò¤??ΤȤǥ᥽?åɥ??Ö¥??????Ȥ??????(3)?????Í¥????Ø¿????Υ᥽?åɥ??Ö¥??????Ȥ?ä??ë¡¢?Ȥ??????ȤǤ??? 467: 468: ????????????Ë¥????Í¥????Ø¿??@code{define-class} ?Þ¥??í¤¬??ۤΤ?????????Þ¤??? 469: 470: @c COMMON 471: @example 472: gosh> (d x-of) 473: #<generic x-of (2)> is an instance of class <generic> 474: slots: 475: name : x-of 476: methods : (#<method (x-of <2d-vector>)> #<method (x-of <2d-point>)>) 477: @end example 478: 479: @c EN 480: In the mainstream dynamic object-oriented languages, a class 481: has many roles; it defines a structure and a type, creates a 482: namespace for its slots and methods, and is responsible for 483: method dispatch. In Gauche, namespace is managed by modules, 484: and method dispatch is handled by generic functions. 485: 486: The default printed representation of object is not very user-friendly. 487: Gauche's @code{write} and @code{display} function call a generic 488: function @code{write-object} when they encounter an instance 489: they don't know how to print. You can define its method 490: specialized to your class to customize how the instance is 491: printed. 492: @c JP 493: ?????Ū?????????Ȼظ?????Ï¡????饹?ˤ???????????????? 494: ???饹?Ϲ?¤?È·????????????Ȥȥ᥽?åɤ??????????? 495: ?᥽?åɤΥǥ????ѥå???????Þ¤???Gauche?Ǥϡ?̾?????⥸?塼?????Æ´?ý¤·¡¢¥á¥½?åɤΥǥ????ѥå?Ï¥????Í¥????Ø¿????Ĥ????Þ¤??? 496: 497: ???Ö¥??????Ȥΰ?????Ï¡??Ç¥Õ¥????Ǥϡ????Þ¤??????ˤ䤵????????????Gauche ??@code{write} ???? @code{display} ?Ø¿???ɤΤ褦?˰?????褤???狼???????ó¥¹¥??󥹤ˤǤ????È¡??????Í¥????Ø¿?ode{write-object} 498: ??Ó¤Þ¤????????????饹?Î¥??ó¥¹¥??󥹤?Τ褦?˰???뤫???????Þ¥??????뤿???????Î¥??饹???ꤷ???᥽?åɤ????뤳?Ȥ??Ǥ??Þ¤??? 499: 500: @c COMMON 501: @example 502: (define-method write-object ((pt <2d-point>) port) 503: (format port "[[~a, ~a]]" (x-of pt) (y-of pt))) 504: 505: (define-method write-object ((vec <2d-vector>) port) 506: (format port "<<~a, ~a>>" (x-of vec) (y-of vec))) 507: @end example 508: 509: @c EN 510: And what you'll get is: 511: @c JP 512: ?Ç¡??ɤ??ʤä????Ȥ????È¡? 513: @c COMMON 514: @example 515: gosh> a-point 516: [[0.0, 3.33]] 517: gosh> d-vector 518: <<-9.0, 7.25>> 519: @end example 520: 521: @c EN 522: If you customize the printed representation to conform srfi-10 523: format, and define a corresponding read-time constructor, 524: you can make your instances to be written-out and read-back 525: just like built-in objects. See @ref{Read-time constructor} for 526: the details. 527: 528: Several built-in functions have similar way to extend their 529: functionality for user-defined objects. For example, if 530: you specialize a generic function @code{object-equal?}, 531: you can compare the instances by @code{equal?}: 532: @c JP 533: srfi-10 ?Î¥Õ¥????ޥåȤ???褦?˰?????ò¥«¥????Þ¥?????????ß¹??ß»? 534: ????Ò¤?????????ʬ??????????饹?Î¥??ó¥¹¥??󥹤?Ȥ߹??????Ö¥??????Ȥ????˽ñ¤½Ð¤??????ᤷ?Ǥ??Þ¤????ܤ?????@ref{Read-time constructor} ?ò¸«¤Æ¤???????? 535: 536: ?????Ĥ???Ȥ߹??ß´Ø¿?桼???????Ö¥??????Ȥ?Ф??????????ǽ????Ǥ??Þ¤??????Ȥ??С?@code{object-equal?} ??ê²½?????? 537: @code{equal?} ??äƥ??ó¥¹¥??󥹤?????Ǥ??Þ¤??? 538: 539: @c COMMON 540: @example 541: (define-method object-equal? ((a <2d-point>) (b <2d-point>)) 542: (and (equal? (x-of a) (x-of b)) 543: (equal? (y-of a) (y-of b)))) 544: 545: (equal? (make <2d-point> :x 1 :y 2) (make <2d-point> :x 1 :y 2)) 546: @result{} #t 547: 548: (equal? (make <2d-point> :x 1 :y 2) (make <2d-point> :x 2 :y 1)) 549: @result{} #f 550: 551: (equal? (make <2d-point> :x 1 :y 2) 'a) 552: @result{} #f 553: 554: (equal? (list (make <2d-point> :x 1 :y 2) 555: (make <2d-point> :x 3 :y 4)) 556: (list (make <2d-point> :x 1 :y 2) 557: (make <2d-point> :x 3 :y 4))) 558: @result{} #t 559: @end example 560: 561: @c EN 562: Let's proceed to more interesting examples. 563: Think of a class @code{<shape>}, 564: which is an entity that can be drawn. 565: As a base class, it keeps 566: common attributes such as a color and line thickness in its slots. 567: @c JP 568: ???Ȥ??⤷?í¤¤??ò¸«¤Æ¤ß¤Þ¤??礦?????ǽ??@code{<shape>} ?Ȥ??????饹 569: ????Þ¤??? 570: ????饹?Ȥ??Æ¡??????????Ȥ??ä????°??ò¥¹¥??Ȥ˻ý¤¿¤»¤Þ¤??? 571: 572: @c COMMON 573: @example 574: (define-class <shape> () 575: ((color :init-value '(0 0 0) :init-keyword :color) 576: (thickness :init-value 2 init-keyword :thickness))) 577: @end example 578: 579: @c EN 580: When an instance is created, @code{make} calls a generic function 581: @code{initialize}, which takes care of initializing slots 582: such as processing init-keywords and init-values. 583: You can customize the initialization behavior by specializing 584: the @code{initialize} method. The @code{initialize} method 585: is called with two arguments, one is a newly created instance, 586: and another is a list of arguments passed to @code{make}. 587: 588: We define a @code{initialize} method for @code{<shape>} class, 589: so that the created shape will be automatically recorded in a global 590: list. Note that we don't want to replace system's 591: @code{initialize} behavior completely, 592: since we still need the init-keywords to be handled. 593: 594: @example 595: (define *shapes* '()) ;; global shape list 596: 597: (define-method initialize ((self <shape>) initargs) 598: (next-method) ;; let the system to handle slot initialization 599: (push! *shapes* self)) ;; record myself to the global list 600: @end example 601: @c JP 602: ???ó¥¹¥??󥹤????????@code{make} ?Ï¥????Í¥????Ø¿?ode{initialize} 603: ??Ó¤Þ¤??????δؿ?init-keyword ??nit-value ???褦?Ê¥????Ȥ????ò¸«¤Þ¤???????@code{initialize} ?᥽?åɤ?ê²½???뤳?Ȥˤ??Æ¡????? 604: ?ο?????ò¥«¥????Þ¥??????뤳?Ȥ??Ǥ??Þ¤???@code{initialize} ?᥽?åɤ??????Ȥ??ƤФ??????ҤȤĤϿ??????????줿???ó¥¹¥??󥹡??⤦?ҤȤĤ?@code{make} ?ˤ錄???줿???ꥹ?ȤǤ??? 605: 606: @code{initialize} ?᥽?åɤ?ode{<shape>} ???饹?????????????줿 607: shape ????ưŪ?Ë¥??í¡¼?Ð¥??ꥹ?Ȥ????????褦?ˤ??Þ¤??礦?? 608: ?????Æ¥??? @code{initialize} ?ο?????????Ö¤??????????Ϥʤ??Ȥ??? 609: ???Ȥ?????Ƥ????????init-keyword ???????????ɬ??????뤫?????? 610: 611: @example 612: (define *shapes* '()) ;; ???í¡¼?Ð¥? shape ?Υꥹ?? 613: (define-method initialize ((self <shape>) initargs) 614: (next-method) ;; ???Î¥????ƥब?????Ȥν??????ò¤¹¤????ˤ??? (push! *shapes* self)) ;; ??ʬ???Ȥò¥°¥í¡¼?Ð¥??ꥹ?Ȥ???????end example 615: 616: @c EN 617: The trick is a special method, @code{next-method}. It can only be 618: used inside a method body, and calls @emph{less specific method} 619: of the same generic function---typically, it means you call the 620: same method of superclass. 621: Most object-oriented languages have the concept of calling 622: superclass's method. Because of multiple-argument 623: dispatching and multiple inheritance, @code{next-method} is 624: a little bit more complicated, but the basic idea is the same. 625: 626: So, what's the superclass of @code{<shape>}? In fact, all 627: Scheme-defined class inherits a class called @code{<object>}. 628: And it is @code{<object>}'s initialize method which takes care 629: of slot initialization. After calling @code{next-method} 630: within your @code{initialize} method, you can assume all 631: the slots are properly initialized. So it is generally the 632: first thing in your @code{initialize} method to call @code{next-method}. 633: 634: Let's inspect the above code. When you call 635: @code{(make <shape> args @dots{})}, the system allocates 636: memory for an instance of @code{<shape>}, and calls 637: @code{initialize} generic function with the instance and 638: @code{args @dots{}}. It is dispatched to the @code{initialize} 639: method you just defined. In it, you call @code{next-method}, 640: which in turn calls @code{<object>} class's @code{initialize} 641: method. It initializes the instance with init-values and init-keywords. 642: After it returns, you register the new @code{<shape>} instance 643: to the global shape list @code{*shapes*}. 644: 645: The @code{<shape>} class represents just an abstract concept of 646: shape. Now we define some concrete drawable shapes, by 647: @emph{subclassing} the @code{<shape>} class. 648: @c JP 649: ?ųݤ??Ï¡????ʥ᥽?Ã¥?@code{next-method} ?ˤ??????????? 650: ?᥽?Ã¥??Τ???????Ȥ??Þ¤???????????Í¥????Ø¿?@emph{??????ٹ礬??????᥽?Ã¥???Ó¤Þ¤?????????ŵ??Ū?ˤ??????Ñ¡????饹??????᥽?åɤ?֤Ȥ??????Ȥ?????Þ¤??? 651: ?ۤȤ?Î¥????????Ȼظ?????Ï¡??????Ñ¡????饹?Υ᥽?åɤ?֤Ȥ??? 652: ??ǰ??????????¿?Ű??????ѥå????ŷѾ??Τ??? @code{next-method} 653: ?Ͼ???Ê£???ˤϤʤäƤ??Þ¤?????????Ê¥????Ç¥?????????Ǥ??? 654: 655: ???Æ¡??Ǥ?@code{<shape>} ?Î¥????Ñ¡????饹?Ϥʤ???礦???¤ϡ? 656: ???٤Ƥ?Scheme ??????줿???饹??@code{<object>} ?Ȥ??????饹???????Þ¤????????ȤΤ??ɤ??ò¸«¤Æ¤????Ï¡?@code{<object>} ???????᥽?åɤʤΤǤ?????ʬ??????? @code{initialize} ?᥽?Ã¥?? 657: @code{next-method} ??Ó¤???????ȤǤϡ????٤ƤΥ????Ȥ? 658: ????????Ë¥??????????줿?Ȥߤʤ??Þ¤????Ȥ????櫓?Ç¡???ʬ??????? 659: @code{initialize} ?Τʤ???̾?ǽ????Ù¤????Ȥ?@code{next-method} 660: ??Ö¤??ȤǤ??? 661: 662: ???????ɤ?????Ƥߤޤ??礦??@code{(make <shape> args @dots{})} ??֤ȡ? 663: ?????Æ¥? @code{<shape>} ?Î¥??ó¥¹¥??󥹤Τ?????????ݤ??? 664: @code{initialize} ?????Í¥????Ø¿?????Î¥??ó¥¹¥??󥹤?@code{args @dots{}} 665: ?ǸƤӤޤ????????????Þ¼?ʬ??????? @code{initialize} ?˥ǥ????ѥå?????????????? @code{next-method} ???????줬?????@code{<object>} 666: ???饹??@code{initialize} ?᥽?åɤ?Ó¤Þ¤??????????Î¥??ó¥¹¥??󥹤?init-value ??init-keyword ?ǽ???????????@code{next-method} ?????ɤä? 667: ???È¡??????? @code{<shape>} ???ó¥¹¥??󥹤ò¥°¥í¡¼?Ð¥? shape ?ꥹ?Ȥ?@code{*shapes*} ???????Þ¤??? 668: 669: ????@code{<shape>} ???饹??shape ???Ū??ǰ??????Ƥ????????Þ¤????Ǥϡ??????Ĥ??ζ??????ǽ??shape ??ode{<shape>} ??@emph{???Ö¥??饹??}?ˤ???????Þ¤??礦?? 670: 671: @c COMMON 672: @example 673: (define-class <point-shape> (<shape>) 674: ((point :init-form (make <2d-point>) :init-keyword :point))) 675: 676: (define-class <polyline-shape> (<shape>) 677: ((points :init-value '() :init-keyword :points) 678: (closed :init-value #f :init-keyword :closed))) 679: @end example 680: 681: @c EN 682: Note the second argument passed to @code{define-class}. 683: It indicates that @code{<point-shape>} and @code{<polyline-shape>} 684: inherit slots of @code{<shape>} class, and also instances of 685: those subclasses can be accepted wherever an instance of 686: @code{<shape>} class is accepted. 687: 688: The @code{<point-shape>} adds one slot, @code{point}, which 689: contains an instance of @code{<2d-point>} defined in the beginning 690: of this section. The @code{<polyline-shape>} class stores 691: a list of points, and a flag, which specifies whether the end 692: point of the polyline is connected to its starting point or not. 693: 694: Inheritance is a powerful mechanism that should be used with care, 695: or it easily result a code which is untractable 696: ("Object-oriented programming offers a sustainable way to 697: write spaghetti code.", as Paul Graham says in his article 698: "The Hundred-Year Language"). 699: The rule of thumb is to make a subclass when you need a subtype. 700: The inheritance of slots is just something that comes with, 701: but it shouldn't be the main reason to do subclassing. 702: You can always "include" the substructure, as is done in 703: @code{<point-shape>} class. 704: 705: There appeared a new slot option in @code{<point-shape>} class. 706: The @code{:init-form} slot option specifies the default value of 707: the slot when init-keyword is not given to @code{make} method. 708: However, unlike @code{:init-value}, with which the value is 709: evaluated at the time the class is defined, 710: the value with @code{:init-form} is evaluated when the system 711: actually needs the value. So, in the @code{<point-shape>} instance, 712: the default @code{<2d-point>} instance is only created if the 713: @code{<point-shape>} instance is created without having @code{:point} 714: init-keyword argument. 715: 716: A shape may be drawn in different formats for different devices. 717: For now, we just consider a PostScript output. To make the @code{draw} 718: method polymorphic, we define a postscript output device class, 719: @code{<ps-device>}. 720: 721: @c JP 722: @code{define-class} ??????????Ƥ???????????? 723: @code{<point-shape>} ???? @code{<polyline-shape>} ?? @code{<shape>} 724: ???饹?Î¥????Ȥ?????Ƥ??뤳?Ȥò¼¨¤??Ƥ??Þ¤?????????@code{<shape>} 725: ???饹??????????Ϥ??٤ơ??????Î¥??Ö¥??饹?Ǥ???????뤳???⼨???Ƥ??Þ¤??? 726: 727: @code{<point-shape>} ?ˤ?@code{point} ?Ȥ????????Ȥ??ҤȤ?ɲ????????Þ¤??????Î¥????ȤϤ?????ǽ?????????@code{<2d-point>} ?????ó¥¹¥??󥹤??Þ¤???@code{<polyline-shape>} ???饹???Υꥹ?È¡? 728: ?ե饰??????Þ¤????ե饰????Ñ·?Υ饤?󤬽???È»??Ĥʤ??Ǥ??뤫 729: ?ɤ?????ꤷ?Þ¤??? 730: 731: ?Ѿ??ϤȤꤢ?Ĥ????????ɬ??ʶ???ʵ????Ǥ??????ä??ꤹ???????????ǽ?Ê¥????ɤ??Ǥ???????????(Paul Graham ?Ï¡??ǯ?θ???Ȥ??? 732: ????ʤ??Ç¡??Ö¥??Ö¥??????Ȼظ??×¥í¥°???󥰤ϥ??Ñ¥??åƥ??????ɤ???????????󶡤??Ƥ??????פȸ?äƤ??????Ë¡?) 733: ?и?§???餤???È¥??Ö¥????פ?ɬ??ʤȤ??Ë¥??Ö¥??饹??????褤?褦?Ǥ??? 734: ?????ȤηѾ???տ魯???ˤ??ǤϤ????????????Ö¥??饹???Τ??? 735: ???????ƤϤ????Þ¤???code{<point-shape>} ???饹?Ǥ????褦?????Ö¥??ȥ饯????Ö¥??󥯥롼?ɡפ??뤳?ȤϾ??Ǥ????Ǥ??? 736: 737: @code{<point-shape>} ???饹?Ë¿??????????È¥??×¥????????????????? 738: @code{:init-form} ?Ȥ????????È¥??×¥????Ï¡?init-keyword ?? 739: @code{make} ????????ʤ??ä??Ȥ??Τ??Î¥????ȤΥǥե??????ꤷ?Þ¤??? 740: ???????????饹???????????? @code{:init-value} ??ͤȤϤ???äơ? 741: ????@code{:init-form} ???????Ï¥????ƥब?ºݤΤ???ͤ?פȤ??? 742: ?Ȥ????????????????????äơ?@code{<point-shape>} ?Î¥??ó¥¹¥????Ǥϡ?@code{<point-shape>} ???ó¥¹¥??󥹤? @code{:point} ??????ɰ? 743: ?錄???줺???????줿?Ȥ??ˤΤߡ??Ç¥Õ¥?????@code{<2d-point>} 744: ???ó¥¹¥??󥹤??????????? 745: