[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
10.2 Creating and accessing objects
Bigloo automatically creates functions to allocate and manipulate objects. Let us suppose the class declaration:
(class class field1::type1 (* field2::type2))
Theses functions are:
- A nil instance:
(class-nil::class)
This function returns the NIL pre-existing class instance. This instance plays the role of
void *
in C ornull
in Java. The value of each field is unspecified but correct with respect to the Bigloo type system. Each call toclass-nil
returns the same object (in the sense ofeq?
). - A creator:
(make-class::class ::type1 ::long ::type2)
This function allocates a fresh instance of class and fills the field values with the argument. The length of the indexed field field2 is given as argument of the function.
Example:
(class truc x::char (* y::bstring))
The prototype of the allocation function is:
(make-truc::truc x::char y-len::long y::bstring)
The indexed values of the
y
andz
fields will be set to the values of the formal parametersy
andz
respectively. - A filler:
(fill-class! ::class ::type1 ::long ::type2)
This function accepts the same arguments as the creator augmented with one allocated instance. This instance is filled up with the provided values. For indexed fields, the same initial value is used to fill up the array of values.
- A type checker:
(class?::bool obj::obj)
This function returns
#t
if obj is an instance of class or an instance of a sub-class of class, otherwise, it returns#f
. - Accessors and mutators:
(class-field_1::type_1 ::class) (class-field_1-set!::obj ::class ::type_1) (class-field_2-len::long ::class) (class-field_2-ref::type_2 ::class ::long) (class-field_2-set!::obj ::class ::long ::type_2)
Declaring a field
read-only
prevents Bigloo from generating an associatedclass-field_i-set!
function. The length of the indexed field isread-only
. Thus they do not have mutator functions.
Some syntax helps with allocation and access to objects.
- bigloo syntax: with-access::class obj (binding…) body
-
A reference to any of the variables defined in as a binding is replaced by the appropriate field access form. This is true for both reference and assignment. A binding is either a symbol or a list of two symbols. In the first place, it denotes a field. In the second case, it denotes an aliases field.
For instance:
(with-access::point p (x (y1 y)) (with-access::point p2 (y) (set! x (- x)) (set! y1 (- y1 y)))) is equivalent to: (begin (point-x-set! p (- (point-x p))) (point-y-set! p (- (point-y p) (point-y p2))))
When an indexed field is referenced inside the binding part of a
with-access
form, the functions that accesses and changes the fields are bound inside the body of thewith-access
. In addition, a variable reporting the length of the field is also bound. For a field fd, the getter function is(fd-ref offset)
, the setter is(fd-set! offset value)
, the length variable isfd-len
. For instance:(with-access::truc o (y) (print "length: " y-len) (print "old y-ref(0): " (y-ref 0)) (y-set! 0 "foo") (print "new y-ref(0): " (y-ref 0))) is equivalent to: (begin (print "length: " (truc-y-len o)) (print "old y-ref(0): " (truc-y-ref o 0)) (truc-y-set! o 0 "foo") (print "new y-ref(0): " (truc-y-ref o 0)))
- bigloo syntax: instantiate::class (ident value)…
-
This forms allocates object of class class and fills the fields with values found in the list of parameters (note that field are explicitly named and that there is no ordering for field naming). Field values which are not provided in the parameter list must have been declared with a
default
value which is used to initialize the corresponding field.For instance:
(make-point 0 0)
is equivalent to:
(instantiate::point (x 0) (y 0))
Indexed field must be provided with exactly two values. The first is the length of the indexed field and the second is the default value of each element of the indexed field.
- bigloo syntax: co-instantiate ((var value) …) body
-
This form is only available from compiled modules. In other words, it is not available from the interpreter. It permits the creation of recursive instances. It is specially useful for creating instances for which class declarations contain cyclic type references (for instance a class
c1
for a which a field is declared of classc2
and a classc2
for which a class is declared of typec1
). The syntax of aco-instantiate
form is similar to alet
form. However the only legal values areinstantiate
forms. The variables introduced in the binding of aco-instantiate
form are bound in body. In addition, they are partially bound in the values expressions. In a value position, a variable var can only be used to set the value of a field of an instantiated class. It cannot be used in any calculus. Example:(module obj-example (export (class c1 a b o2::c2) (class c2 x y o1::c1))) (co-instantiate ((o1 (instantiate::c1 (a 10) (b 20) (o2 o2))) (o2 (instantiate::c2 (x 10) (y 20) (o1 o1)))) (+ (c2-x (c1-o2 o1)) (c2-y (c1-o2 o1)))) ⇒ 30
- bigloo syntax: duplicate::class obj (ident value)…
-
This forms allocates an instance of class class. The field values of the new object are picked up from the field values of the old object unless they are explicitly given in the parameter list.
For instance:
(with-access::point old (x) (make-point x 10))
is equivalent to:
(duplicate::point old (y 10))
Indexed field must be provided with exactly two values. The first is the length of the indexed field and the second is the default value of each element of the indexed field.
Here is an example of creations and mutations of a complex object:
(module foo (export (class named-tab name::string (* els::int)))) ;; a function that prints a named-tab (define (print-tab tab) (display* (named-tab-name tab) ": ") (let loop ((i (-fx (named-tab-els-len tab) 1))) (if (=fx i -1) (newline) (begin (display* #\( i " " (named-tab-els-ref tab i) ") ") (loop (-fx i 1)))))) ;; we allocate a named-tab object with ;; 5 els, each of them initialized to 0 (define a-tab (instantiate::named-tab (name "example") (els 5 0))) ;; we print its elements (print-tab a-tab) ;; we change the values of the indexed field ;; els by setting values from 0 to 4 (let loop ((i (-fx (named-tab-els-len a-tab) 1))) (if (=fx i -1) 'done (begin (named-tab-els-set! a-tab i i) (loop (-fx i 1))))) ;; we re-print it (print-tab a-tab)
This will produce the following output:
example: (4 0) (3 0) (2 0) (1 0) (0 0) example: (4 4) (3 3) (2 2) (1 1) (0 0)
[ << ] | [ < ] | [ Up ] | [ > ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
This document was generated on October 23, 2011 using texi2html 5.0.