Is there for Perl?

I would prefer to do this:

say $shop->ShopperDueDate->andand->day_name(); 

vs. this is:

 say $shop->ShopperDueDate->day_name() if $shop->ShopperDueDate; 

Any ideas?

(This idea is inspired by the Ruby andand extension .)

(He's actually inspired by Groovy, but most people don't know that ;-)

update . I think both possibly () and eval {} are good solutions. This is not a ruby, so I cannot expect all methods / functions to be left to right, so maybe this can be of help. And then, of course, eval really is the perl way to do this.

+4
source share
4 answers

I think I just wrote. I just uploaded it to CPAN, you can find it here .

+4
source

You can use the Perl eval operator to throw exceptions, including from attempts to call methods in the undefined argument:

 eval { say $shop->ShopperDueDate->day_name(); }; 

Since eval returns the last processed statement or undef on error, you can write the name of the day in a variable as follows:

 my $day_name = eval { $shop->ShopperDueDate->day_name(); }; 

If you really want to check the exception, you can see the special variable $@ . This will usually be a simple line for Perl's built-in exceptions, but may be the full exception object if the exception comes from autodie or other code that uses object exceptions.

 eval { say $shop->ShopperDueDate->day_name(); }; if ( $@ ) { say "The error was: $@ "; } 

It is also possible to group a sequence of commands using the eval block. The following will only check if it was on the weekend if we had no exceptions thrown when searching for $day_name .

 eval { my $day_name = $shop->ShopperDueDate->day_name(); if ($day_name ~~ [ 'Saturday', 'Sunday' ] ) { say "I like weekends"; } }; 

You can think of eval as the same as try from other languages; indeed, if you use the Error module from CPAN, you can even write its try . It is also worth noting that the block form of eval (which I demonstrated above) is not related to performance penalties and compiled along with the rest of your code. The string form of eval (which I haven't shown yet) is a completely different beast and should be used sparingly, if at all.

eval technically considered an assertion in Perl and, therefore, is one of the few places where you will see a half-point at the end of the block. This is easy to forget if you are not using eval regularly.

Floor

+9
source

I assume your second example should be better:

 say $shop->ShopperDueDate ? $shop->ShopperDueDate->day_name() : undef; 

instead of what it actually says.

In any case, you cannot do this with this syntax without a source filter, because undef not an object, but a unary operator, so it cannot have any methods.

Instead, consider the following:

 package noop; our $maybe = bless [], 'noop'; sub AUTOLOAD { undef }; 

This $noop::maybe is an object; all its methods return undef . Elsewhere you will have a regular function:

 sub maybe { $_[0] || $noop::maybe; } 

Then you can write this:

 say maybe($shop->ShopperDueDate)->day_name() 

This works because "maybe" returns its argument if true, otherwise it returns our $noop::maybe object, which has methods that always return undef.

EDIT: Bugfix! the syntax ->andand-> can be used without a source filter, using XS , which tricks Perl internals. Leon Timmermans implemented this implementation. It replaces the undef() function globally, so it will probably be much slower than my method.

+9
source

Something like (untested):

 use Object::Generic::False; sub UNIVERSAL::andand { $_[0] || Object::Generic::False->false } 

UNIVERSAL is automatically a subclass of all other classes, so it provides and / or for all objects. (Obviously, creating methods in UNIVERSAL has the potential for conflicts or unexpected actions at a distance, so it cannot be used lightly.) If the object on which the andand method is called is true, return it; otherwise returns a common false object that returns itself for any method call used for it.

0
source

All Articles