Continues from previous week.
Feel free to submit a merge request or open a ticket if you found any issues with this post. We highly appreciate and welcome your feedback.
For a quick overview, go through the original tasks and recap of the weekly challenge.
Task #1
CPAN modules used: Const::Fast
, English
, Modern::Perl
, POSIX
, Test::More
, Try::Tiny
, constant
, experimental
, feature
, strict
, utf8
, warnings
Based on the submitted answers, there were three ways used by participants to solve this task. We will look into these approaches.
The eval
function or the poor man catch approach. The most common approach used by majority of the participants. Start with the submission by Adam Russell which demonstrate the basic usage of eval
function. The solution can be further improved as seen in the submission by Ndelucca, Lars Balker and Andrezgz.
Javier Luque used of double eval
functions was rather unique even though the eval
usage have violated the Perl Critic’s rule of Return value of eval not tested [ErrorHandling::RequireCheckingReturnValueOfEval]
.
# Return the $answer or undef if we can't divide by 0
sub divide_by_zero_check {
my $answer;
eval { $answer = eval shift; };
return $answer;
}
Other participants that used this approach were Anton Fedotov, Duane Powell, Dave Cross, Athanasius, Ruben Westerberg, Burkhard Nickels, Laurent Rosenfeld, Rage311, Jaldhar H. Vyas, Yet Ebreo, Duncan C White, Steven Wilson, Colin Crain and Joelle Maslak.
Both Laurent Rosenfeld and E. Choroba have discovered that eval
function have a bug in earlier Perl version that prevents trapping the error. Therefore, using the Try::Tiny
CPAN module is a good alternative.
This brings us to the second approach, using the Try::Tiny
CPAN module which allows us to handle exception using a try-catch block. Yes, this may be syntactic sugar but definitely a better abstraction than the low level eval
function. Dave Jacoby, Lars Thegler, Lubos Kolouch, Pete Houston and E. Choroba took this approach.
Take note of how E. Choroba presented the error conditions in the division
subroutine. Consistency was enforced by returning a state and result of the calculation as shown below. While this may seem subjective, the code showed good taste in coding, especially for API or library design.
sub division {
my ($numerator, $denominator) = @_;
try {
{ safe => 1, result => $numerator / $denominator }
} catch {
{ safe => 0, error => $_ }
}
}
Lastly, the unorthodox approach. No one but Maxim Kolodyazhny (solution shown below) and Vyacheslav Volgarev. 42
is definitely answer to everything since the ASCII code for asterisk (*
), a wildcard for everything is 42
.
use constant ANSWER2EVERYTHING => 42;
sub harmless_division {
my ($x, $y ) = @_;
return if $y == int $y && ( ANSWER2EVERYTHING ^ $y ) == ANSWER2EVERYTHING;
$x / $y;
}
Special mention of Burkhard Nickels solution which used operator overload to solve this task.
Task #2
CPAN modules used: Const::Fast
, Data::Dumper
, Encode
, English
, File::Basename
, Getopt::Long
, Modern::Perl
, Test::More
, feature
, lib
, strict
, utf8
, warnings
For this task, look at the solution by Lars Balker was a good example to demonstrate how symbolic references works. Most submitted answers were more or less the same variation of this answer with their own coding style.
use v5.10;
use warnings;
use strict;
my $var = shift // die "usage: $0 <varname>";
no strict 'refs'; # we're specifically abusing this feature
$$var = $var;
say $$var;
Next, read the blog post by Laurent Rosenfeld and Perl FAQ on the history, issues, and usage of using a dynamic variable in Perl.
SEE ALSO
(1) Perl Weekly Challenge - 031 by Javier Luque
(2) Dynamic Zero with Raku by Arne Sommer
(3) Perl Weekly Challenge 031 by Adam Russell
(4) Perl Weekly Challenge 31: Illegal Division by Zero and Dynamic Variables by Laurent Rosenfeld
(5) Perl Weekly Challenge: Week 31 by Jaldhar H. Vyas
(6) Perl Weekly Challenge 031: Division by Zero & Dynamic Variable Name by E. Choroba