From: Don Armstrong Date: Mon, 27 May 2019 23:07:27 +0000 (-0700) Subject: document Debbugs::Collection X-Git-Url: https://git.donarmstrong.com/?p=debbugs.git;a=commitdiff_plain;h=70225b764c2773a0230ab393d7dba6c0275fdfac document Debbugs::Collection --- diff --git a/Debbugs/Collection.pm b/Debbugs/Collection.pm index 808d77f..552c0f3 100644 --- a/Debbugs/Collection.pm +++ b/Debbugs/Collection.pm @@ -12,6 +12,8 @@ Debbugs::Collection -- Collection base class which can generate lots of objects =head1 SYNOPSIS +This base class is designed for holding collections of objects which can be +uniquely identified by a key and added/generated by that same key. =head1 DESCRIPTION @@ -23,9 +25,102 @@ use Mouse; use strictures 2; use namespace::autoclean; use List::AllUtils qw(pairmap); +use Carp qw(croak); extends 'Debbugs::OOBase'; +=head1 METHODS + +=head2 Debbugs::Collection->new(%params|$params) + +Creates a new Debbugs::Collection object. + +Parameters: + +=over + +=item universe + +To avoid unnecessarily constructing new members, collections have a universe to +which existing members can be obtained from. By default the universe is this +collection. Generally, you should create exactly one universe for each +collection type. + +=item schema + +Optional Debbugs::Schema object + + +=back + +=head2 $collection->members() + +Returns list of members of this collection + +=head2 $collection->members_ref() + +Returns an ARRAYREF of members of this collection + +=head2 $collection->keys_of_members() + +Returns a list of the keys of all members of this collection + +=head2 $collection->member_key($member) + +Given a member, returns the key of that member + +=head2 $collection->exists($member_key) + +Returns true if a member with $member_key exists in the collection + +=head2 $collection->clone() + +Returns a clone of this collection with the same universe as this collection + +=head2 $collection->limit(@member_keys) + +Returns a new collection limited to the list of member keys passed + +=head2 $collection->add($member) + +Add a member to this collection + +=head2 $collection->add_by_key($member_key) + +Add a member to this collection by key + +=head2 $collection->get($member_key) + +Get member(s) by key, returning undef for keys which do not exist in the +collection + +=head2 $collection->get_or_add_by_key($member_key) + +Get or add a member by the member key. + +=head2 $collection->count() + +Return the number of members in this collection + +=head2 $collection->grep({$_ eq 5}) + +Return the members in this collection which satisfy the condition, setting $_ +locally to each member object + +=head2 $collection->join(', ') + +Returns the keys of the members of this collection joined + +=head2 $collection->apply({$_*2}) $collection->map({$_*2}) + +Return the list of applying BLOCK to each member + +=head2 $collection->sort({$a <=> $b}) + +Return the list of members sorted by BLOCK + +=cut + has 'members' => (is => 'bare', isa => 'ArrayRef', traits => ['Array'], @@ -84,6 +179,11 @@ sub _add_member_hash { wantarray ? return @return: return $return[0]; } +=head2 $collection->universe + + +=cut + has 'universe' => (is => 'ro', isa => 'Debbugs::Collection', required => 1, @@ -121,21 +221,21 @@ sub limit { # $limit->_set_universe($self->universe); $limit->_set_members([]); $limit->_clear_member_hash(); - $limit->add($self->universe->get_or_create(@_)) if @_; + $limit->add($self->universe->get_or_add_by_key(@_)) if @_; return $limit; } -sub get_or_create { +sub get_or_add_by_key { my $self = shift; return () unless @_; my @return; my @exists; my @need_to_add; for my $i (0..$#_) { - # we assume that if it's already a blessed reference, that it's the right - if (blessed($_[$i])) { - $return[$i] = - $_[$i]; + # we assume that if it's already a blessed reference, that it's the + # right object to return + if (ref $_[$i]) { + croak "Passed a reference instead of a key to get_or_add_by_key"; } elsif ($self->_member_key_exists($_[$i])) { push @exists,$i; @@ -197,8 +297,9 @@ sub add { sub get { my $self = shift; - return map {$self->_get_member($_)} + my @res = map {$self->_get_member($_)} $self->_get_member_hash(@_); + wantarray?@res:$res[0]; } @@ -206,11 +307,22 @@ sub member_key { return $_[1]; } +sub keys_of_members { + my $self = shift; + return $self->map(sub {$self->member_key($_[0])}); +} + sub exists { my $self = shift; return $self->_member_key_exists($self->member_key($_[0])); } +sub join { + my $self = shift; + my $joiner = shift; + return CORE::join($joiner,$self->keys_of_members); +} + sub _build_member_hash { my $self = shift; my $hash = {}; @@ -224,7 +336,16 @@ sub _build_member_hash { sub CARP_TRACE { my $self = shift; - return 'Debbugs::Collection={n_members='.$self->count().'}'; + my @members = $self->members; + if (@members > 5) { + @members = map {$self->member_key($_)} + @members[0..4]; + push @members,'...'; + } else { + @members = map {$self->member_key($_)} @members; + } + return __PACKAGE__.'={n_members='.$self->count(). + ',members=('.CORE::join(',',@members).')}'; }