PerlX::Maybe - return a pair only if they are both defined
You once wrote:
my $bob = Person->new( defined $name ? (name => $name) : (), defined $age ? (age => $age) : (), );
Now you can write:
use PerlX::Maybe; my $bob = Person->new( maybe name => $name, maybe age => $age, );
Moose classes (and some other classes) distinguish between an attribute being unset and the attribute being set to undef. Supplying a constructor arguments like this:
my $bob = Person->new( name => $name, age => $age, );
Will result in the name and age attributes possibly being set to undef (if the corresponding $name and $age variables are not defined), which may violate the Person class' type constraints.
name
age
$name
$age
(Note: if you are the author of the class in question, you can solve this using MooseX::UndefTolerant. However, some of us are stuck using non-UndefTolerant classes written by third parties.)
To ensure that the Person constructor does not try to set a name or age at all when they are undefined, ugly looking code like this is often used:
or:
my $bob = Person->new( (name => $name) x!!(defined $name), (age => $age) x!!(defined $age), );
A slightly more elegant solution is the maybe function.
maybe
maybe $x => $y, @rest
This function checks that $x and $y are both defined. If they are, it returns them both as a list; otherwise it returns the empty list.
$x
$y
If @rest is provided, it is unconditionally appended to the end of whatever list is returned.
@rest
The combination of these behaviours allows the following very sugary syntax to "just work".
my $bob = Person->new( name => $name, address => $addr, maybe phone => $tel, maybe email => $email, unique_id => $id, );
This function is exported by default.
provided $condition, $x => $y, @rest
Like maybe but allows you to use a custom condition expression:
my $bob = Person->new( name => $name, address => $addr, provided length($tel), phone => $tel, provided $email =~ /\@/, email => $email, unique_id => $id, );
This function is not exported by default.
provided_deref $condition, $r, @rest
Like provided but dereferences the second argument into list context:
provided
my $bob = Person->new( name => $name, address => $addr, provided length($tel), phone => $tel, provided $email =~ /\@/, email => $email, provided_deref $employee, sub { employee_id => $employee->employee_id, maybe department => $employee->department, }, unique_id => $id, );
The second argument may be a HASH or ARRAY reference. It may also be a CODE reference, which will be called in list context. If it is a blessed object, it will be treated as if it were a HASH reference (internally it could be another type of reference with overloading). A code reference can be used if evaluation of the second argument should only occur if the condition is met (e.g. to prevent method calls on an uninitialised value).
provided_deref_with_maybe $condition, $r, @rest
Like provide_deref but will perform maybe on each key-value pair in the dereferenced values.
provide_deref
my $bob = Person->new( name => $name, address => $addr, provided length($tel), phone => $tel, provided $email =~ /\@/, email => $email, provided_deref_with_maybe $employee, $employee, unique_id => $id, );
Also, if the second argument is a blessed object, it will also skip any 'private' attributes (keys starting with an underscore).
It not only "just works", it "DWIM"s!
PerlX::Maybe::IMPLEMENTATION
Indicates whether the XS backend PerlX::Maybe::XS was loaded.
If you install PerlX::Maybe::XS, a faster XS-based implementation will be used instead of the pure Perl functions. My basic benchmarking experiments seem to show this to be around 30% faster.
Currently there are no XS implementations of the provided_deref and provided_deref_with_maybe functions. Contributions welcome.
provided_deref
provided_deref_with_maybe
The environment variable PERLX_MAYBE_IMPLEMENTATION may be set to "PP" to prevent the XS backend from loading.
PERLX_MAYBE_IMPLEMENTATION
"PP"
Only maybe is exported by default. You can request other functions by name:
use PerlX::Maybe "maybe", "provided";
Or to export everything:
use PerlX::Maybe ":all";
If Exporter::Tiny is installed, you can rename imports:
use PerlX::Maybe "maybe" => { -as => "perhaps" };
Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=PerlX-Maybe.
Syntax::Feature::Maybe, PerlX::Maybe::XS.
MooseX::UndefTolerant, PerlX::Perform, Exporter.
Toby Inkster <tobyink@cpan.org>.
provided_deref and provided_deref_with_maybe by Theo van Hoesel.
This software is copyright (c) 2012-2013, 2018 by Toby Inkster.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
To install PerlX::Maybe, copy and paste the appropriate command in to your terminal.
cpanm
cpanm PerlX::Maybe
CPAN shell
perl -MCPAN -e shell install PerlX::Maybe
For more information on module installation, please visit the detailed CPAN module installation guide.