I want share an headache with you due to the Perl's loop control until structure.
I'm currently happily reading, with some profit i hope, High Order Perl and so far, apart from some math base i do not have, i can quite afford it. and i very like it.
While explaining iterators apllied to permutations the author, with the usual kindness, come back a little to present a simpler problem: an odometer.
Realized that the odometer is that set of little wheels showing how many kilometers my kawasaki GPZ 750 divoured in his history, i looked at the subroutine proposed with a "ah ok... is very simple. i can get it.." approach.
This line, clear in the result wanted, mazed and puzzled me:
This is the original code of the sub with a little prepended code just to call it, putted by me.<P> until ($odometer[$wheel] < 9 || $wheel < 0)<P>
use strict; use warnings; my @odometer = qw(0 0); for (1..$ARGV[0]) { print "was: @odometer\t"; @odometer = increment_odometer(@odometer); @odometer ? (print join ' ', @odometer) : (print "No more Wheels t +o turn! $!" and exit) ; print "\n"; } sub increment_odometer { my @odometer = @_; my $wheel = $#odometer; # start at rightmost wheel until ($odometer[$wheel] < 9 || $wheel < 0) { $odometer[$wheel] = 0; $wheel--; # next wheel to the left } if ($wheel < 0) { return; # fell off the left end; no more sequences } else { $odometer[$wheel]++; # this wheel now turns one no +tch return @odometer; } }
It does not appear the first attempt using an LABEL if redo solution because i think i'm too young to use LABELs.until ($odometer[$wheel] < 9 || $wheel < 0) #ok original #negated direct form also ok while ( !($odometer[$wheel] < 9 || $wheel < 0) ) while ($odometer[$wheel] > 9 || $wheel < 0) # NO while ($odometer[$wheel] > 8 || $wheel < 0) # OK but NOT for greter th +an limit of the odometer! #Use of uninitialized value in numeric eq (==) at C:\SCRIPTS +\odometer.pl line 27. #Modification of non-creatable array value attempted, subscr +ipt -3 at C:\SCRIPTS\odometer.pl line 26. #getting: 9 9-> while ($odometer[$wheel] == 9 || $wheel < 0) # OK but NOT for greter +than limit of the odometer! #Use of uninitialized value in numeric eq (==) at C:\SCRIPTS +\odometer.pl line 27. #Modification of non-creatable array value attempted, subscr +ipt -3 at C:\SCRIPTS\odometer.pl line 26. #getting: 9 9-> while ($odometer[$wheel] == 9 && $wheel >= 0) # OK
But really the negation of ($odometer[$wheel] < 9 || $wheel < 0) is ($odometer[$wheel] == 9 && $wheel >= 0) ?
This is not a critic to Perl or about the choice of words in the language or a request to abolish the poor until is only something i want to share about the problematic enlace between a logical language and a spooken one.
L*
UPDATE 10 Nov 2017 found a similar article at blogs.perl.org and left here my comments and a link to this post.
|
|---|