package PerlX::Maybe; use 5.008; use strict; our (@EXPORT, @ISA); BEGIN { $PerlX::Maybe::AUTHORITY = 'cpan:TOBYINK'; $PerlX::Maybe::VERSION = '0.002'; require Exporter; @ISA = qw/Exporter/; @EXPORT = qw/maybe/; } sub maybe ($$@) { if (defined $_[0] and defined $_[1]) { @_ } else { (scalar @_ > 1) ? @_[2 .. $#_] : qw() } } __FILE__ __END__ =head1 NAME PerlX::Maybe - return a pair only if they are both defined =head1 SYNOPSIS You once wrote: my $bob = Person->new( defined $name ? (name => $name) : (), defined $age ? (age => $age) : (), ); Now you can write: my $bob = Person->new( maybe name => $name, maybe age => $age, ); =head1 DESCRIPTION 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 C and C attributes possibly being set to undef (if the corresponding C<$name> and C<$age> variables are not defined), which may violate the Person class' type constraints. (Note: if you are the I of the class in question, you can solve this using L. 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: my $bob = Person->new( defined $name ? (name => $name) : (), defined $age ? (age => $age) : (), ); or: my $bob = Person->new( (name => $name) x!!(defined $name), (age => $age) x!!(defined $age), ); A slightly more elegant solution is the C function: =head2 C<< maybe $x => $y, @rest >> This function checks that C<< $x >> and C<< $y >> are both defined. If they are, it returns them both as a list; otherwise it returns the empty list. If C<< @rest >> is provided, it is unconditionally appended to the end of whatever list is returned. 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. =head1 BUGS Please report any bugs to L. =head1 SEE ALSO L. L, L, L. =head1 AUTHOR Toby Inkster Etobyink@cpan.orgE. =head1 COPYRIGHT AND LICENCE This software is copyright (c) 2012 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. =head1 DISCLAIMER OF WARRANTIES 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.