| Class-Composite documentation | Contained in the Class-Composite distribution. |
Class::Composite::Container - Collection of Class::Composite::Element
use Class::Composite::Container; my $c = Class::Composite::Container->new(); $c->nextElement(); $c->resetPointer(); $c->nextElement(); $obj = $c->getElement(); $list = $c->getElements(2, 5);
Class::Composite::Container acts as a collection of elements.
Class::Composite
Parameters are 'elements' and 'elempointer' init is useful for inheritance, you don't need to redefine new(), but you can redefined init(). See Base::Class documentation.
Get/Set elements array
Gets or sets the elements pointer. The pointer is garenteed to be between 0 and the number of elements - 1
The addElement() method adds elements to the collection. Returns the collection if ok.
Same than addElement, but flatten everything before adding. If you add a collection, it will add all elements individually, not the collection. Returns the collection if ok.
Returns true if $elem can be added to the container. The element must be of the same type than elementType() (see Class::Composite) or is undef. This method is called for each element added to the collection.
Returns the element asked. If $index < 0 it backtracks from the last element. If no index is given, returns the current element.
Returns an array ref of elements. $start and $end are indexes. $end is optional - if not given all elements after $start are returned. If neither $start and $end are given, returns all elements.
If no $index is given, the current element is removed. Rearrange the collection by shifting to the left the elements > $elem. Returns the element removed if ok.
Reset the collection and returns the collection.
Returns the number of elements
Returns the current element and increments the internal index. You can use in a while loop such as:
while ( my $elem = $container->nextElement ) { ... }
Decrements the internal index and returns the element
Increments the internal index
Decrements the internal index
Reset pointer to retrieve the first element again Returns the pointer value before being reset
Set pointer to $index. The internal index will be set to 0 if $index < 0 and will be set to the number of elements - 1 if $index >= number of elements Returns the pointer's former value
Class::Composite, Class::Composite::Element
"Pierre Denis" <pdenis@fotango.com>
Copyright (C) 2002, Fotango Ltd. All rights reserved.
This is free software. This software may be modified and/or distributed under the same terms as Perl itself.
| Class-Composite documentation | Contained in the Class-Composite distribution. |
package Class::Composite::Container; use strict; use warnings::register; use Scalar::Util qw ( blessed ); use base qw( Class::Composite ); our $VERSION = 0.1;
sub init : method { my $self = shift; $self->SUPER::init( @_ ); $self->{elements} ||= []; $self->{elempointer} ||= 0; $self; }
sub elements : method { my $self = shift; my $elem = shift or return $self->{elements}; ref $elem eq 'ARRAY' or return $self->_warn("Not an array ref: $elem"); $self->{elements} = $elem; $self; }
sub elempointer : method { my ($self, $elem) = @_; defined $elem or return $self->{elempointer}; $elem = $self->nOfElements - 1 if $elem >= $self->nOfElements; $elem = 0 if $elem < 0; $self->{elempointer} = int $elem; $self; }
sub addElement : method { my ($self, @args) = @_; foreach (@args) { $self->_addThis(this => $_) or return; } $self; }
sub addElementFlat : method { my ($self, @args) = @_; foreach (@args) { $self->_addThis( this => $_, flat => 1 ) or return; } $self; } # # _addThis(this => $id or $object, flat => 0/1) # sub _addThis { my ($self, %args) = @_; my $object = $args{this}; my $flat = $args{flat} || 0; $self->checkElement( $object ) or return $self->_warn("Element to add is not of type ".$self->elementType); if ($flat and ref($object)) { my $objects = $object->isa('Class::Composite::Container') ? $object->getLeaves : [ $object ]; $self->_addTheseObj( $objects ); } else { $self->_addTheseObj( [$object] ); } } sub _addTheseObj { my ($self, $objects) = @_; push @{$self->{elements}}, @$objects; }
sub checkElement { my ($self, $elem) = @_; my $type = $self->elementType or return 1; return 1 unless defined $elem; if (blessed($elem)) { return $elem->isa($type); } else { return ref($elem) eq $type; } }
sub getElement { my ($self, $id) = @_; $id = $self->elempointer unless defined $id; return unless exists $self->{elements}; if (defined( $self->{elements}->[$id] )) { return $self->{elements}->[$id]; } else { return undef; } }
sub getElements { my ($self, $start, $end) = @_; $start ||= 0; return [] unless $self->{elements}; $end = @{$self->{elements}} - 1 unless defined $end; [ @{$self->{elements}}[$start .. $end] ]; }
sub removeElement { my ($self, $index) = @_; $index = $self->elempointer unless defined $index; splice @{ $self->{elements} }, $index, 1; }
sub removeAll { my $self = shift; $self->{elements} = []; $self->{elempointer} = 0; $self; }
sub nOfElements { scalar(@{$_[0]->{elements}}) || 0; }
sub nextElement { my $self = shift; $self->getElement( $self->incrPointer() ); }
sub previousElement { my $self = shift; $self->decrPointer or do { $self->resetPointer(); return }; $self->getElement(); }
sub incrPointer : method { $_[0]->{elempointer}++; }
sub decrPointer : method { $_[0]->{elempointer}--; }
sub resetPointer : method { my $self = shift; my $ret = $self->{elempointer}; $self->{elempointer} = shift || 0; $ret; }
sub setPointer : method { my ($self, $i) = @_; my $current = $self->{elempointer}; $i = $self->nOfElements - 1 if ($i >= $self->nOfElements); $i = 0 if ($i < 0); $self->{elempointer} = $i; $current; } 1; __END__