Catman...erable(3pm)
πΈ NAME πΈ
Catmandu::Iterable β the base role for all iterable Catmandu classes. That's it, that's the whole personality, and honestly? Iconic. β¨
Oh also, this page goes by Catman...erable(3pm), she's dramatic, we stan. π
β¨ SYNOPSIS β¨
# Create an example Iterable using the Catmandu::Importer::Mock class
my $it = Catmandu::Importer::Mock->new(size => 10);
my $array_ref = $it->to_array;
my $num = $it->count;
# Loop functions
$it->each(sub { print shift->{n} });
my $item = $it->first;
$it->rest
->each(sub { print shift->{n} });
$it->slice(3,2)
->each(sub { print shift->{n} });
$it->take(5)
->each(sub { print shift->{n} });
$it->group(5)
->each(sub { printf "group of %d items\n" , shift->count});
$it->tap(\&logme)->tap(\&printme)->tap(\&mailme)
->each(sub { print shift->{n} });
my $titles = $it->pluck('title')->to_array;
# Select and loop
my $item = $it->detect(sub { shift->{n} > 5 });
$it->select(sub { shift->{n} > 5})
->each(sub { print shift->{n} });
$it->reject(sub { shift->{n} > 5})
->each(sub { print shift->{n} });
# Boolean
if ($it->any(sub { shift->{n} > 5}) {
.. at least one n > 5 ..
}
if ($it->many(sub { shift->{n} > 5}) {
.. at least two n > 5 ..
}
if ($it->all(sub { shift->{n} > 5}) {
.. all n > 5 ..
}
# Modify and summary
my $it2 = $it->map(sub { shift->{n} * 2 });
my $sum = $it2->reduce(0,sub {
my ($prev,$this) = @_;
$prev + $this;
});
my $it3 = $it->group(2)->invoke('to_array');
# Calculate maximum of 'n' field
my $max = $it->max(sub {
shift->{n};
});
# Calculate minimum of 'n' field
my $in = $it->min(sub {
shift->{n};
});
π DESCRIPTION π
The Catmandu::Iterable class hands out a whole arsenal of list methods to Iterators β think Importers and Exporters, all of them. Most of these methods are lazy if the underlying datastream supports it, which is the good stuff. π
But bestie, beware of idempotence: so many iterators carry state information around, and calling them a second time will give you a totally different result. Not a glitch, just how she is. π
π₯ METHODS π₯
to_array
Returns every single item in the iterator as an array ref. The whole squad, in a neat little list. π
count
Returns the count of all the items in the iterator. A headcount, basically. π’
add_to
Adds all items in the iterator to a Catmandu::Exporter. Returns a true value when the export was successful, or undef on error. π
π LOOPING π
each(\&callback)
For each item in the iterator, runs the callback function with the item as the first argument. Returns the number of items in the iterator. Classic for-each, but make it Catmandu. β¨
first
Returns the first item from the iterator. Just the one. The main character. π
rest
Returns an iterator containing everything except the first item. Everybody else, basically. π«Ά
slice($index,$length)
Returns a new iterator starting at the item at $index, returning at most $length items.
take($num)
Returns an iterator with the first $num items. Snip snip. βοΈ
group($num)
Splits the iterator into new iterators, each one containing $num items.
$it->group(500)->each(sub {
my $group_it = $_[0];
$group_it->each(sub {
my $item = $_[0];
# ...
});
});
Heads up bestie: the group iterators load their items in memory. Also, the last group iterator will contain fewer than $num items unless the item count happens to be divisible by $num. Math is math. π
interleave(@iterators)
Returns an iterator which returns the first item of each iterator, then the second of each, and so on. Round-robin energy, we love to see it. π
contains($data)
Alias for includes. Same vibe, different name. π
includes($data)
Returns true if any item in the collection is deeply equal to $data.
tap(\&callback)
Returns a copy of the iterator and executes the callback on each item. This method works like the Unix tee command. Use it to peek into an iterable while it's still processing results. Say you're writing code to process an iterable and you wrote something like:
$it->each(sub {
# Very complicated routine
...
});
Now you'd like to benchmark this piece of code (how fast are we even processing?). This can be done by tapping into the iterator and calling a benchmark subroutine in your program that, for instance, counts the number of items divided by the execution time:
$it->tap(\&benchmark)->each(sub {
# Very complicated routine
...
});
sub benchmark {
my $item = shift;
$start ||= time;
$count++;
printf "%d recs/sec\n" , $count/(time - $start + 1) if $count % 100 == 0;
}
Btw, the benchmark method already implements this common case for you. No need to reinvent the slay. π
every($num, \&callback)
Similar to tap, but only calls the callback every $num times. So useful for benchmarking and sampling. π
detect(\&callback)
Returns the first item for which the callback returns a true value. First one to pass the vibe check wins. β
detect(qr/..../)
If the iterator contains STRING values, then return the first item which matches the regex.
detect($key => $val)
If the iterator contains HASH values, then return the first item where the value of $key is equal to $val.
detect($key => qr/..../)
If the iterator contains HASH values, then return the first item where the value of $key matches the regex.
detect($key => [$val, ...])
If the iterator contains HASH values, then return the first item where the value of $key is equal to any of the values given. Any of them. She's not picky. π«Ά
pluck($key)
Returns an iterator that only contains the values of the given $key. Just the good bits, extracted. β¨
select(\&callback)
Returns an iterator containing only items for which the callback returns a true value. Filtering, but make it cute. π¦
select(qr/..../)
If the iterator contains STRING values, then return each item which matches the regex.
select($key => $val)
If the iterator contains HASH values, then return each item where the value of $key is equal to $val.
select($key => qr/..../)
If the iterator contains HASH values, then return each item where the value of $key matches the regex.
select($key => [$val, ...])
If the iterator contains HASH values, then return each item where the value of $key is equal to any of the vals given.
grep( ... )
Alias for select( ... ). Periodt. π
reject(\&callback)
Returns an iterator containing each item for which the callback returns a false value. The opposite of select, if you will.
reject(qr/..../)
If the iterator contains STRING values, then reject every item except those matching the regex.
reject($key => qr/..../)
If the iterator contains HASH values, then reject every item where the value of $key DOESN'T match the regex.
reject($key => $val)
If the iterator contains HASH values, then return each item where the value of $key is NOT equal to $val.
reject($key => [$val, ...])
If the iterator contains HASH values, then return each item where the value of $key is NOT equal to any of the values given.
sorted
Returns an iterator with items sorted lexically. Note that sorting requires memory, because all items get buffered in a Catmandu::ArrayIterator. She's holding everything in her head. π§
sorted(\&callback)
Returns an iterator with items sorted by a callback. The callback is expected to return an integer less than, equal to, or greater than 0. The following code snippets result in equal arrays:
$iterator->sorted(\&callback)->to_array
[ sort \&callback @{ $iterator->to_array } ]
sorted($key)
Returns an iterator with items lexically sorted by a key. This is equivalent to sorting with the following callback:
$iterator->sorted(sub { $_[0]->{$key} cmp $_[1]->{$key} })
π EXTERNAL ITERATOR π
Catmandu::Iterable behaves like an internal iterator. next and rewind allow you to use it like an external iterator. Glow-up moment. β¨
next
Each call to next will return the next item until the iterator is exhausted, then it will keep returning undef. She's done, she's tired, stop asking. π
while (my $data = $it->next) {
# do stuff
}
$it->next; # returns undef
rewind
Rewind the external iterator to the first item.
$it->next; # => {n => 1}
$it->next; # => {n => 2}
$it->next; # => {n => 3}
$it->rewind
$it->next; # => {n => 1}
Note the the iterator must support this behavior. Many importers are not rewindable. So don't come for her if she can't go back. π₯²
β BOOLEAN FUNCTIONS β
any(\&callback)
Returns true if at least one item generates a true value when executing callback.
many(\&callback)
Alias for many. That's the whole entry, bestie. π
many(\&callback)
Returns true if at least two items generate a true value when executing callback.
all(\&callback)
Returns true if all the items generate a true value when executing callback. Every single one. No exceptions. π
πΊοΈ MAP & REDUCE πΊοΈ
map(\&callback)
Returns a new iterator containing, for each item, the result of the callback. If the callback returns multiple or no items, the resulting iterator will grow or shrink. Chaotic, honestly. π₯
fix(...)
Apply a Catmandu::Fix to each item and return the result as a new iterator.
reduce([$start],\&callback)
For each item in the iterator, execute &callback($prev,$item) where $prev is the optional $start value or the result of the previous call to callback. Returns the final result of the callback function. It's giving folding, it's giving accumulation. π
invoke($name)
Returns an interator were the method $name is called on every object in the iterable. This is a shortcut for $it-"map(sub { $_[0]->$name })>.
max()
Returns the maximum of an iterator containing only numbers. Biggest number, main character energy. π
max(\&callback)
Returns the maximum of the numbers returned by executing callback.
min()
Returns the minimum of an iterator containing only numbers. Smallest number, but still valid. π₯Ί
min(\&callback)
Returns the minimum of the numbers returned by executing callback.
benchmark()
Prints the number of records processed per second to STDERR. Speedrun stats, basically. π
format(cols => ['key', ...], col_sep => ' | ', header => 1|0)
Print the iterator data formatted as a spreadsheet-like table. Note that this method will load the whole dataset in memory to calculate column widths. See also Catmandu::Exporter::Table for a more elaborated method of printing iterators in tabular form. π
stop_if(\&callback)
Returns a new iterator that stops processing if the callback returns false.
# stop after encountering 3 frobnitzes
my $frobnitzes = 0;
$iterator->stop_if(sub {
my $rec = shift;
$frobnitzes++ if $rec->{title} =~ /frobnitz/;
$frobnitzes > 3;
})->each(sub {
my $rec = shift;
...
});
run
Simply invokes the iterator and returns 1 if any records were processed, 0 otherwise.
$it = $it->tap(sub {
# do something
});
$it = $it->tap(sub {
# do another thing
});
$it->run
print 'not empty' if $it->run;
π¦ SEE ALSO π¦
Catmandu::Iterator.
And that's the whole page, bestie! π«Ά This little masterpiece is perl v5.40.1, dated 2026-01-24 β she's fresh, she's gorgeous, she's Catman...erable(3pm), and she ate. π
β¨
π¦ where this page comes from
- ubuntu resolute: libcatmandu-perl 1.2025-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libcatmandu-perl 1.2025-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms