Var::Pairs(3pm)
πΈ NAME πΈ
Var::Pairs β okay so bestie, this is the Var::Pairs(3pm) page, and it's literally the module for OO iterators and pair constructors for variables. That's the whole vibe. π
β¨ VERSION β¨
This doc describes Var::Pairs version 0.004002. Noted. Iconic. π
π¦ SYNOPSIS π¦
use Var::Pairs;
# pairs() lists all OO pairs from arrays and hashes...
for my $next (pairs @array) {
say $next->index, ' has the value ', $next->value;
}
# each_pair() iterates OO pairs from arrays and hashes...
while (my $next = each_pair %hash) {
say $next->key, ' had the value ', $next->value;
$next->value++;
}
# to_kv() converts vars into var_name => var_value pairs...
Sub::Install::install_sub({to_kv $code, $from, $into});
# invert() reverses a one-to-many mapping correctly...
my %reverse_mapping = invert %mapping;
my %reverse_lookup = invert @data;
π DESCRIPTION π
So this module exports a small number of subroutines that justβ¦ hand you some Perl 6 conveniences in your humble Perl 5. No cap. Specifically, it exports several subroutines that make key/value pair interactions with hashes and arrays so much easier. π«Ά
π INTERFACE π
π Array and hash iterators π
pairs %hashpairs @arraypairs $hash_or_array_ref
In list context, pairs() hands you back a list of pair objects β each one carrying a single key/index and its value from the argument. But in scalar and void contexts? It throws an exception. No pairs for you there, bestie. π
The typical list usage is:
for my $pair (pairs %container) {
# ...do something with $pair
}
The whole intent here is to be a safe and reliable glow-up replacement for the built-in each() function β specifically, one you can actually use in for loops. π₯
kvs %hashkvs @arraykvs $hash_or_array_ref
In list context, kvs() returns a list of alternating keys and values. So kvs %hash flattens the hash into (key, value, key, value...) and kvs @array flattens the array into (index, value, index, value...). π«
And in scalar and void contexts? kvs() throws an exception too. Consistency, periodt.
The most typical use is populating a hash from an array:
my %hash = kvs @array;
# does the same as:
my %hash; @hash{0..$#array} = @array;
each_pair %hasheach_pair @arrayeach_pair $hash_or_array_refeach_pair $subroutine_ref
In all contexts, each_pair() returns a single pair object holding the key/index and value of the next element in the argument. One at a time. So chill.
Here's the slay part: a separate internal iterator gets created for every single call to each_pair(). Which means you can nest multiple calls to each_pair() over the same container variable and they will not interact with each other. Unlike multiple calls to each(), which is a foot-shooting situation. π
When the iterator runs out, the next call to each_pair() returns undef or an empty list (depends on context) and resets the iterator. It also resets when execution leaves the block where each_pair() was called. So like, last-ing out of the middle of an iterated loop does the right thing. Good behavior fr fr.
The typical usage is:
while (my $pair = each_pair %container) {
# ...do something with $pair->key and $pair->value
}
Note though β using pairs() in a for loop is the preferred idiom:
for my $pair (pairs %container) {
# ...do something with $pair->key and $pair->value
}
Oh and each_pair() can also be handed a reference to a subroutine, in which case that sub gets used directly as the iterator. π§
When iterated, that iterator subroutine is called in list context and is expected to return a single value on each call (i.e. the next value to be iterated), or an empty list when the iterator is exhausted.
For example:
# Calling this sub returns a reference to an anonymous iterator sub...
sub count_down {
my ($from, $to) = @_;
return sub {
return () if $from < $to; # End of iterator
return $from--; # Next iterated value
}
}
# Build a 10-->1 countdown and iterate it...
while (my $next = each_pair count_down(10, 1)) {
say $next->value;
}
each_kv %hasheach_kv @arrayeach_kv $hash_or_array_refeach_kv $subroutine_ref
This one is basically each_pair()'s twin, except in list contexts each_kv() returns a list of two elements: the key/index and the value of the next element in the argument. In scalar contexts, you just get the next key. Simple as. β¨
Same deal as each_pair() β a separate internal iterator per call to each_kv(), so nesting multiple calls over the same container variable is totally fine and they won't interact with each other. Unlike each(). Again. π€
When the iterator is exhausted, the next call to each_kv() returns undef in scalar context or an empty list in list context, and resets the iterator. It also resets when execution leaves the block where each_kv() is called.
The typical list usage is:
while (my ($key1, $val1) = each_kv %container) {
while (my ($key2, $val2) = each_kv %container) {
# ...do something with the two keys and two values
}
}
The typical scalar usage is:
while (my $key1 = each_kv %container) {
while (my $key2 = each_kv %container) {
# ...do something with the two keys
}
}
In other words, each_kv() is a drop-in replacement for Perl's built-in each() β with two exceptions. One's a gift, one's a limit:
- The advantage: you can nest
each_kv()iterations over the same variable without shooting yourself in the foot. π - The limitation: unlike
each(),each_kv()does not reset when you call thekeysfunction on the hash you're iterating. Sorry bestie. π
each_value %hasheach_value @arrayeach_value $hash_or_array_refeach_value $subroutine_ref
each_value() works exactly like each_kv(), except in all contexts it just returns the value being iterated β not the key, not the key/value combo. Just the value. Minimalist. π
For example:
# Build a 10-->1 countdown and iterate it...
while (my ($next) = each_value count_down(10, -10)) {
say $next;
}
while (my $value1 = each_value %container) {
while (my $value2 = each_value %container) {
# ...do something with the two values
}
}
Heads up: if your iterator can return a false value β like the0from thecount_down()iterator in the example above β then you should calleach_value()in list context (as in thecount_down()example) so that false value doesn't prematurely terminate yourwhileloop. Lowkey a trap. π
%hash->pairs@array->pairs$hash_or_array_ref->pairs%hash->kvs@array->kvs$hash_or_array_ref->kvs%hash->each_pair@array->each_pair$hash_or_array_ref->each_pair%hash->each_kv@array->each_kv$hash_or_array_ref->each_kv%hash->each_value@array->each_value$hash_or_array_ref->each_value
If you have the autobox module installed, you can use this OO syntax too. π¦ And apart from their call syntax, these OO forms are exactly the same as the subroutine-based interface described above.
π Pairs π
$pair->key
Returns a copy of the key of the pair, if the pair came from a hash. Returns a copy of the index of the pair, if the pair came from an array.
$pair->index
Literally nothing but a synonym for $pair->key. Use whichever one suits your purpose, your program, or your predilections. Main character choice. π
$pair->value
Returns the value of the pair, as an lvalue. That is:
for my $item (pairs %items) {
say $item->value
if $item->key =~ /\d/;
}
will print the value of every entry in the %items hash whose key includes a digit.
And:
for my $item (pairs %items) {
$item->value++;
if $item->key =~ /^Q/;
}
will increment each value in the %items hash whose key starts with 'Q'.
$pair->kv
Returns a two-element list containing copies of the key and the value of the pair. That is:
for my $item (pairs %items) {
my ($k, $v) = $item->kv;
say $v
if $k =~ /\d/;
}
will print the value of every entry in the %items hash whose key includes a digit.
$pair
When used as a string, a pair gets converted into a suitable representation for a pair, namely: key => value. Cute, right? πΈ
0 + $pair
Pairs cannot be used as numbers: an exception is thrown. Do not do this. Not the vibe. π
if ($pair) {...}
When a pair is used as a boolean, it is always true. Always. Every time. Periodt. β¨
π§ Named pair constructors π§
to_pair $scalar, @array, %hash, $etc
The to_pair subroutine takes one or more variables and converts each of them into a single Pair object. The Pair's key is the name of the variable (minus its leading sigil), and the value is the value of the variable (if it's a scalar) or a reference to the variable (if it's an array or hash).
That is:
to_pair $scalar, @array, %hash, $etc
is equivalent to:
Pair->new( scalar => $scalar ),
Pair->new( array => \@array ),
Pair->new( hash => \%hash ),
Pair->new( etc => $etc )
This is especially useful for generating modern sets of named arguments for other subroutines. For example:
Sub::Install::install_sub(to_pair $code, $from, $into);
instead of:
Sub::Install::install_sub(
Pair->new(code => $code),
Pair->new(from => $from),
Pair->new(into => $into)
);
Look at that glow-up. Obsessed. ππ
to_kv $scalar, @array, %hash, $etc
The to_kv() subroutine takes one or more variables and converts each of them into a key => value sequence β that is, a two-element list, rather than a Pair object. π
Okay so same energy as to_pair(): the key is the name of the variable (minus its leading sigil), and the value is the value of the variable (if it's a scalar) or a reference to the variable (if it's an array or hash). No cap.
Which is giving:
to_kv $scalar, @array, %hash, $etc
is literally the same as:
scalar => $scalar, array => \@array, hash => \%hash, etc => $etc
This is lowkey iconic for generating traditional sets of named arguments for other subroutines. Like, for example:
Sub::Install::install_sub({to_kv $code, $from, $into});
instead of this whole situation:
Sub::Install::install_sub({code => $code, from => $from, into => $into});
β¨ Array and hash inverters β¨
invert
invert %hash
invert @array
invert $hash_or_array_ref
Bestie, the invert subroutine takes a single hash or array (or a reference to either) and returns a list of alternating keys and value, where each key is a value from the original variable and each corresponding value is a reference to an array containing the original key(s). This list is typically used to initialize a second hash, which can then be used as a reverse mapping. In other words:
my %hash = ( a => 1, b => 2, c => 1, d => 1, e => 2, f => 3 );
my %inversion = invert %hash;
is equivalent to:
my %inversion = (
1 => ['a', 'c', 'd'],
2 => ['b', 'e'],
3 => ['f'],
);
And invert correctly handles the many-to-many case where some of the values in the original are array references. It's giving flexible. For example:
my %hash = ( a => [1,2], b => 2, c => [1,3], d => 1, e => [3,2], f => 3 );
my %inversion = invert %hash;
is equivalent to:
my %inversion = (
1 => ['a', 'c', 'd'],
2 => ['a', 'b', 'e'],
3 => ['c', 'e', 'f'],
);
invert_pairs
invert_pairs %hash
invert_pairs @array
invert_pairs $hash_or_array_ref
invert_pairs() acts exactly like invert(), except that it returns a list of Pair objects (like pairs() does). Periodt.
This is not useful for initializing other hashes, but it's highkey handy for debugging a reverse mapping:
say for invert_pairs %hash;
OO syntax with autobox
%hash->invert
%hash->invert_pairs
@array->invert
@array->invert_pairs
$hash_or_array_ref->invert
$hash_or_array_ref->invert_pairs
If you have the autobox module installed, you can use this OO syntax as well. Apart from their call syntax, these OO forms are exactly the same as the subroutine-based interfaces described above. No notes.
π DIAGNOSTICS π
Argument to %s must be hash or array (not %s)β Except forto_pair()andto_kv(), all of the subroutines exported by this module only operate on hashes, arrays, or references to hashes or arrays. Asking for thepairsinside a scalar, typeglob, or other entity is meaningless; they're simply not structured as collections of keyed values. Like, read the room, scalar.Useless use of pairs() in void contextUseless use of kvs() in void contextUseless use of invert() in void contextβ None of these subroutines has any side-effects, so calling them in void context is a waste of time. It's giving nothing.Invalid call to pairs() in scalar contextInvalid call to kvs() in scalar contextInvalid call to invert() in scalar contextβ All these subroutines return a list, so in scalar context you just get a count (which there are cheaper and easier ways to obtain). Not the vibe.
The most common case where this error is reported is when pairs() or kvs() is used in a while loop, instead of a for loop. Either change the type of loop, or else use each_pair() or each_kv() instead. Slay.
Can't convert Pair(%s => %s) to a numberβ You attempted to use one of the pair objects returned bypairs()as a number, but the module has no idea how to do that. It's like asking a cat to bark.
You probably need to use $pair->index or $pair->value instead. Iykyk.
π CONFIGURATION AND ENVIRONMENT π
Var::Pairs requires no configuration files or environment variables. Low maintenance queen.
π¦ DEPENDENCIES π¦
The module requires Perl 5.014 and the following modules, bestie:
- Perl 5.14 or later
- Devel::Callsite
- Data::Alias (under Perl 5.20 and earlier)
- PadWalker
To use the optional $container->pairs syntax, you also need the autobox module.
π« INCOMPATIBILITIES π«
None reported. We love a clean slate.
π BUGS AND LIMITATIONS π
No bugs have been reported. Iconic behavior.
Please report any bugs or feature requests to bug-var-pairs@rt.cpan.org, or through the web interface at <http://rt.cpan.org>. Do it for the plot.
each_kv() acts like a true one-time only iterator (in the OO sense), so there is no way to reset its iteration (i.e. the way that calling keys() on a hash or array, resets any each() that is iterating it). If you need to reset partially iterated hashes or arrays, you will need to use some other mechanism to do so. No takebacks.
π«Ά ACKNOWLEDGEMENTS π«Ά
Based on a suggestion by Karl Brodowsky and inspired by several features of Perl 6. Shoutout to Karl.
π AUTHOR π
Damian Conway <DCONWAY@CPAN.org> β the icon himself.
π LICENCE AND COPYRIGHT π
Copyright (c) 2012, Damian Conway <DCONWAY@CPAN.org>. All rights reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See perlartistic. Free is free, bestie.
β οΈ DISCLAIMER OF WARRANTY β οΈ
BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
This page was served fresh on 2023-07-21, from perl v5.36.0, and it's Var::Pairs(3pm) β periodt. π β¨
π¦ where this page comes from
- debian trixie: libvar-pairs-perl 0.004002-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libvar-pairs-perl 0.004002-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libvar-pairs-perl 0.004002-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libvar-pairs-perl 0.004002-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