diff options
| author | drbaggy <js5@sanger.ac.uk> | 2021-04-06 09:24:02 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2021-04-06 09:24:02 +0100 |
| commit | 2b79dbff795727e5ee8227de995c0cc27a92db34 (patch) | |
| tree | 447e9f10632f5390cf8250db66fd0f882f9e990d /challenge-107 | |
| parent | a3af256668c8a6d723e5596ec1f7c6d15c87904f (diff) | |
| download | perlweeklychallenge-club-2b79dbff795727e5ee8227de995c0cc27a92db34.tar.gz perlweeklychallenge-club-2b79dbff795727e5ee8227de995c0cc27a92db34.tar.bz2 perlweeklychallenge-club-2b79dbff795727e5ee8227de995c0cc27a92db34.zip | |
Documentation, some more golfing on ch-2 and an example of the difference between use & require.
Diffstat (limited to 'challenge-107')
| -rw-r--r-- | challenge-107/james-smith/perl/Calc_Require.pm (renamed from challenge-107/james-smith/perl/Calc.pm) | 0 | ||||
| -rw-r--r-- | challenge-107/james-smith/perl/Calc_Use.pm | 11 | ||||
| -rw-r--r-- | challenge-107/james-smith/perl/ch-1.pl | 84 | ||||
| -rw-r--r-- | challenge-107/james-smith/perl/ch-2.pl | 12 |
4 files changed, 105 insertions, 2 deletions
diff --git a/challenge-107/james-smith/perl/Calc.pm b/challenge-107/james-smith/perl/Calc_Require.pm index 4123090fde..4123090fde 100644 --- a/challenge-107/james-smith/perl/Calc.pm +++ b/challenge-107/james-smith/perl/Calc_Require.pm diff --git a/challenge-107/james-smith/perl/Calc_Use.pm b/challenge-107/james-smith/perl/Calc_Use.pm new file mode 100644 index 0000000000..ee777771ca --- /dev/null +++ b/challenge-107/james-smith/perl/Calc_Use.pm @@ -0,0 +1,11 @@ +package Calc_Use; + +use strict; +use warnings; + +sub new { bless {}, shift; } +sub add { } +sub mul { } +sub div { } + +1; diff --git a/challenge-107/james-smith/perl/ch-1.pl b/challenge-107/james-smith/perl/ch-1.pl index 753fe48f64..fff417572c 100644 --- a/challenge-107/james-smith/perl/ch-1.pl +++ b/challenge-107/james-smith/perl/ch-1.pl @@ -43,3 +43,87 @@ while( ++$c && @res<3 ) { say "@res"; +## We can reduce this further - by rewriting the inner if with +## using the && trick. && is evaluated lazily - so that if +## the left hand side is false then the right hand side is not +## evaluated. +## +## So if($x) { y() } can be written as $x && y(); +## +## Similarly - unless($x) { y() } can be written $x || y()] and +## if($x) { y() } else { z() } can be written $x ? y() : z() +## +## This means we can make the statement inside the loop a single +## statement and postfix the while... + +($c,@res) = 0; + +( $c == join q(), + map { scalar @{[ $c=~m{($_)}g ]} } + 0 .. -1 + length $c +) && push @res, $c while ++$c && @res<3; + +say "@res"; + +## Note we have to wrap the "condition" in brackets to force +## it to be evaluated before the && as o/w the line ends in +## 0 .. -1 + length( $x && push @res, $c); +## +## This is why we right the "yoda" looking -1 + length $c as +## if you write length $c - 1 this evaluates to length($c-1)... +## +## I wouldn't do this in "normal" code as I think it can get +## confusing $x && f() is not obviously a piece of logic & +## especially if f() has implicit side effects as here + +## If we don't want to capture the values - but just display +## the results - we can drop this into a perl 1-liner on the +## command liner + +=cut +perl -E '($c-join"",map{0+@{[$c=~/($_)/g]}}0..-1+length$c)||++$n&&say$c while++$c&&$n<3' + +# or + +perl -E '($c-join"",map{0+(@Q=$c=~/($_)/g)}0..-1+length$c)||++$n&&say$c while++$c&&$n<3' +=cut + +## You will note so slightly different tricks here... +## (Mainly because we haven't enabled strict!!) +## +## * We use -E this enables more modern perl features - including say! +## +## * We don't collect results - and we just keep a counter - this time +## we use || and && in the "logic"... +## +## We know ++$n is always going to be true (it starts of +## explicitly) and so we always run say$c if we get to the ++$n.. +## +## Note here - this is a place where it is important to choose ++$n +## rather than the more common $n++, as the first evaluates to 0 +## the first time it is invoked - meaning we would skip the first +## answer... +## +## * We show a different trick to count the elements of the list. +## +## Rather than using the scalar @{[ ]} trick to convert it to +## an array we store it in a variable which makes it an array +## we can then get the length of the array. +## +## As we are keeping the code short - we can replace the keyword +## scalar with a simple 0+ which forces the array to be converted +## into a scalar (and hence returns the length) +## +## * To gain another character as the equality is numeric we can +## rewrite if($a==$b) { f() } as ($a-$b)||f(). +## $a-$b is non-zero (true) if $a!=$b so we can rewrite: +## +## if( $a == $b ) { f() } +## +## as +## +## unless( $a - $b ) { f() } +## +## which we know we mentioned we could rewrite as: +## +## ($a-$b) || f() diff --git a/challenge-107/james-smith/perl/ch-2.pl b/challenge-107/james-smith/perl/ch-2.pl index 7895f22840..7cb40e74a7 100644 --- a/challenge-107/james-smith/perl/ch-2.pl +++ b/challenge-107/james-smith/perl/ch-2.pl @@ -6,11 +6,19 @@ use warnings; use feature qw(say); #use Test::More; use lib '.'; -use Calc; +require Calc_Require; +use Calc_Use; ## %{class}:: contains a list of the methods for the class, ## so we can just dump these (to make it deterministic) we ## sort first.... +## +## We "import" the classes in two ways... use & require. +## +## By "require"ing the class - we don't get the additional +## import method added to the class... (and so get the same +## list of fns as in the question) -say join "\n", sort keys %Calc::; +say "Calc_Require:\n",join "\n ", sort keys %Calc_Require::; +say "Calc_Use:\n",join "\n ", sort keys %Calc_Use::; |
