Crop

 view release on metacpan or  search on metacpan

lib/Crop/Object/Collection.pm  view on Meta::CPAN


use Crop::Error;
use Crop::Util qw/ expose_hashes load_class /;
use Crop::Object::Constants;

use Crop::Debug;

=begin nd
Constructor: new ($bless, $obj)
	Create a new collection of class $bless based on $obj data.

Parameters:
	$bless - items class name
	$obj   - hashes that contain source data for each item-object; optional

Returns:
	Collection - on success; empty Collection if $obj missed
	undef      - error
=cut
sub new {
	my ($class, $bless, $obj) = @_;
	$obj = [] unless defined $obj;
	
	load_class($bless) or return warn "OBJECT|CRIT: Collection cannot load class $bless";

	my $is_simple = $bless->isa('Crop::Object::Simple');

	my (@id, @element);
	for (@$obj) {
		my $item = ref eq $bless ? $_ : $bless->new($_);

		push @element, $item;
		push @id, $_->{id} if $is_simple;
	}

	my $self = bless {
		class    => $bless,
		elements => \@element,
		state    => OBJINIT,
	}, $class;

	$self->{simple} = [] if $is_simple;
	$self->{simple} = \@id if @id;

	$self;
}

=begin nd
Method: Class ( )
	Get the class name of a Collection.
	
Returns:
	string - class name
=cut
sub Class { shift->{class} }

=begin nd
Method: Cleanup ( )
	Remove all the items from Collection.
	
	Still alive items in the warehouse.
Returns:
	$self
=cut
sub Cleanup {
	my $self = shift;
	
	$self->{elements} = [];
	$self->{simple}   = [] if exists $self->{simple};
	
	$self;
}

=begin nd
Method: Find (@filter)
	Find all the elements of Collection that satisfy the @filter.
	
	Despite lookup uses string searching, number attributes are processed fine,
	when the 'eq' operator correctly compares digit.

Parameters:
	@filter - items in key position are names of class attributes and values are values for lookup;
	          will be exposed

Returns:
	Arrayref of items where indexes are in ascending order - if items was found
	Empty arrayref                                         - if no items found
=cut
sub Find {
	my ($self, @filter) = @_;
	my $filter = expose_hashes \@filter;

	my @found;
	ITEM:
	while (my ($i, $item) = each @{$self->{elements}}) {
		exists
					$item->{$_}
				and
					defined $item->{$_}
				and
					$item->{$_} eq $filter->{$_}
			or next ITEM for keys %$filter;
		
		push @found, $i;
	}

	\@found;
}

=begin nd
Method: First (@filter)
	Get a first element of a Collection that satisfy @filter.
	
	If no @filter specified, this method will return an item with index 0.
	No checks for range will performed in this case.

Parameters:
	@filter - hash were keys are names of class attributes and values are values for lookup
	
	Example:
	> my $obj = $collection->Fist(id => 25, color => 'red', {smoke = 'yes'});



( run in 2.190 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )