3.9 Component Objects

A component object is an object in the representation IsComponentObjectRep or a subrepresentation of it. Such an object cobj is built from subobjects that can be accessed via cobj!.name, similar to components of a record. Also analogously to records, values can be assigned to components of cobj via cobj!.name:= val. For the creation of component objects, see Creating Objects.

  • NamesOfComponents( comobj ) F

    For a component object comobj, NamesOfComponents returns a list of strings, which are the names of components currently bound in comobj.

    One must be very careful when using the !. operator, in order to interpret the component in the right way, and even more careful when using the assignment to components using !., in order to keep the information stored in cobj consistent.

    First of all, in the access or assignment to a component as shown above, name must be among the admissible component names for the representation of cobj, see Creating Representations. Second, preferably only few low level functions should use !., whereas this operator should not occur in ``user interactions''.

    Note that even if cobj claims that it is immutable, i.e., if cobj is not in the category IsMutable, access and assignment via !. work. This is necessary for being able to store newly discovered information in immutable objects.

    The following example shows the implementation of an iterator (see Iterators in the Reference Manual) for the domain of integers, which is represented as component object. See Positional Objects for an implementation using positional objects.

    The used succession of integers is 0, 1, -1, 2, -2, 3, -3, ¼, that is, an = n/2 if n is even, and an = (1-n)/2 otherwise.

    IsIntegersIteratorCompRep := NewRepresentation( "IsIntegersIteratorRep",
        IsComponentObjectRep, [ "counter" ] );
    

    The above command creates a new representation (see NewRepresentation) IsIntegersIteratorCompRep, as a subrepresentation of IsComponentObjectRep, and with one admissible component counter. So no other components than counter will be needed.

    InstallMethod( Iterator,
        "method for `Integers'",
        [ IsIntegers ],
        function( Integers )
        return Objectify( NewType( IteratorsFamily,
                                       IsIterator
                                   and IsIntegersIteratorCompRep ),
                          rec( counter := 0 ) );
        end );
    

    After the above method installation, one can already ask for Iterator( Integers ). Note that exactly the domain of integers is described by the filter IsIntegers.

    By the call to NewType, the returned object lies in the family containing all iterators, which is IteratorsFamily, it lies in the category IsIterator and in the representation IsIntegersIteratorCompRep; furthermore, it has the component counter with value 0.

    What is missing now are methods for the two basic operations of iterators, namely IsDoneIterator and NextIterator. The former must always return false, since there are infinitely many integers. The latter must return the next integer in the iteration, and update the information stored in the iterator, that is, increase the value of the component counter.

    InstallMethod( IsDoneIterator,
        "method for iterator of `Integers'",
        [ IsIterator and IsIntegersIteratorCompRep ],
        ReturnFalse );
    
    InstallMethod( NextIterator,
        "method for iterator of `Integers'",
        [ IsIntegersIteratorCompRep ],
        function( iter )
        iter!.counter:= iter!.counter + 1;
        if iter!.counter mod 2 = 0 then
          return iter!.counter / 2;
        else
          return ( 1 - iter!.counter ) / 2;
        fi;
        end );
    

    [Top] [Previous] [Up] [Next] [Index]

    GAP 4 manual
    February 2000