composite-slot.scm 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. ;;; installed-scm-file
  2. ;;;; Copyright (C) 1999, 2000, 2001, 2006 Free Software Foundation, Inc.
  3. ;;;;
  4. ;;;; This library is free software; you can redistribute it and/or
  5. ;;;; modify it under the terms of the GNU Lesser General Public
  6. ;;;; License as published by the Free Software Foundation; either
  7. ;;;; version 3 of the License, or (at your option) any later version.
  8. ;;;;
  9. ;;;; This library is distributed in the hope that it will be useful,
  10. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. ;;;; Lesser General Public License for more details.
  13. ;;;;
  14. ;;;; You should have received a copy of the GNU Lesser General Public
  15. ;;;; License along with this library; if not, write to the Free Software
  16. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. ;;;;
  18. ;;;; This software is a derivative work of other copyrighted softwares; the
  19. ;;;; copyright notices of these softwares are placed in the file COPYRIGHTS
  20. ;;;;
  21. ;;;; This file is based upon composite-slot.stklos from the STk
  22. ;;;; distribution by Erick Gallesio <eg@unice.fr>.
  23. ;;;;
  24. (define-module (oop goops composite-slot)
  25. :use-module (oop goops)
  26. :export (<composite-class>))
  27. ;;;
  28. ;;; (define-class CLASS SUPERS
  29. ;;; ...
  30. ;;; (OBJECT ...)
  31. ;;; ...
  32. ;;; (SLOT #:allocation #:propagated
  33. ;;; #:propagate-to '(PROPAGATION ...))
  34. ;;; ...
  35. ;;; #:metaclass <composite-class>)
  36. ;;;
  37. ;;; PROPAGATION ::= OBJECT | (OBJECT TARGETSLOT)
  38. ;;;
  39. ;;; The slot SLOT will be propagated to the slot TARGETSLOT in the object
  40. ;;; stored in slot OBJECT. If TARGETSLOT is omitted, assume that the target
  41. ;;; slot is named SLOT.
  42. ;;;
  43. (define-class <composite-class> (<class>))
  44. (define-method (compute-get-n-set (class <composite-class>) slot)
  45. (if (eq? (slot-definition-allocation slot) #:propagated)
  46. (compute-propagated-get-n-set slot)
  47. (next-method)))
  48. (define (compute-propagated-get-n-set s)
  49. (let ((prop (get-keyword #:propagate-to (cdr s) #f))
  50. (s-name (slot-definition-name s)))
  51. (if (not prop)
  52. (goops-error "Propagation not specified for slot ~S" s-name))
  53. (if (not (pair? prop))
  54. (goops-error "Bad propagation list for slot ~S" s-name))
  55. (let ((objects (map (lambda (p) (if (pair? p) (car p) p)) prop))
  56. (slots (map (lambda (p) (if (pair? p) (cadr p) s-name)) prop)))
  57. (let ((first-object (car objects))
  58. (first-slot (car slots)))
  59. (list
  60. ;; The getter
  61. (lambda (o)
  62. (slot-ref (slot-ref o first-object) first-slot))
  63. ;; The setter
  64. (if (null? (cdr objects))
  65. (lambda (o v)
  66. (slot-set! (slot-ref o first-object) first-slot v))
  67. (lambda (o v)
  68. (for-each (lambda (object slot)
  69. (slot-set! (slot-ref o object) slot v))
  70. objects
  71. slots))))))))