[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

9.10 gauche.mop.validator - Slot with validator

Module: gauche.mop.validator
Provides a metaclass that adds :validator slot option.

Class: <validator-meta>
This metaclass adds a feature that the class can validate a value before being set to the slot. For example, if you want to guarantee that a certain slot always holds a string value, you can make a procedure be called before the slot is modified, either by slot-ref or by a setter method. In the procedure you can either rejects a value except string, or coerce the value to a string.

The validator procedure can be set per each slot by using :validator slot option. The procedure takes two values, the instance and the value to be set. Whatever the procedure returns is set to the actual slot value. See the following example:

 
(define-class <v> ()
  ((a :accessor a-of
      :validator (lambda (obj value) (x->string value)))
   (b :accessor b-of
      :validator (lambda (obj value)
                   (if (integer? value)
                       value
                       (error "integer required for slot b")))))
  :metaclass <validator-meta>)

(define v (make <v>))
(slot-set! v 'a 'foo)
(slot-ref v 'a) => "foo"

(set! (a-of v) 1234)
(a-of v) => "1234"

(slot-set! v 'b 55)
(slot-ref v 'b) => 55

(slot-set! v 'b 3.4) => error
(set! (b-of v) 3.4)  => error

You can specify default slot value (:init-value etc.) with :validator. In that case, the initialization method of the instance calls the validator with the specified default value, if :init-keyword is not given.

 
(define-class <v> ()
  ((a :initform 'foo :init-keyword :a
      :validator (lambda (obj value) (x->string value)))))

(slot-ref (make <v>) 'a)        => "foo"
(slot-ref (make <v> :a 555) 'a) => "555"

It looks similar to the virtual slot, but note that a slot with validator has an actual storage in the instance, while a virtual slot doesn't.

It is also a good example of customizing how the slots are accessed using the metaobject protocol. This feature is implemented by only a dozen lines of code.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Ken Dickey on November, 28 2002 using texi2html