Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^2: loop surprise

by pryrt (Abbot)
on Apr 03, 2018 at 18:20 UTC ( [id://1212274]=note: print w/replies, xml ) Need Help??


in reply to Re: loop surprise
in thread loop surprise

Personally, I wouldn't break out on a condition related to the value of $i itself in such a loop, but I often run across circumstances such that I want to use the loop variable to store the last condition that was valid, when looping through a list of valid or invalid conditions. For example,

my $condNum = 0; for $condNum ( 1 .. 10 ) { forceSituation( $conditions[condNum] ); my $result = measureSituation(); push @results, $result; last if $result->is_error(); more_manipulation(); # possibly do more stuff for this condition, +but only if it's not an error } datalog( value => $condNum, llim => 9.9, hlim => 10.1, name => 'number + of situations tested' ); datalog( value => fn(@results), llim => -2.7182818, hlim => 3.1415926, + name => 'result of those situations' )
... That loop wouldn't work in perl. But it doesn't seem an abuse of the loop counter, to me, to use the loop counter as the indicator of how many situations were actually tested. The code above seems more natural to me than
my $lastCondNum = 0; for my $condNum ( 1 .. 10 ) { ... $lastCondNum=$condNum, last if $result->is_error() ... } ...
Why require a second variable just to store the last condition number it happened to be in, when the loop variable seems a natural storage device for that information?

(In these situations, I'm generally in a hardware-specific language, not Perl, so that one annoyance of Perl doesn't usually affect me. But there are a plethora in the hardware-specific language that I wish it did more like Perl does, so not a fair balance, in my opinion. :-( )

Replies are listed 'Best First'.
Re^3: loop surprise
by AnomalousMonk (Archbishop) on Apr 03, 2018 at 18:48 UTC
    my $condNum = 0; for $condNum ( 1 .. 10 ) { forceSituation( $conditions[condNum] ); my $result = measureSituation(); ...; last if $result->is_error(); ... } datalog( value => $condNum, ...); ...

    But in that case, why not use a C-style loop

    c:\@Work\Perl\monks>perl -wMstrict -le "use constant N_MAX => 10; ;; my $nCond; ;; CONDITION: for ($nCond = 1; $nCond <= N_MAX; ++$nCond) { print $nCond; last CONDITION if $nCond >= 3; } ;; print qq{only made it to condition $nCond} if $nCond < N_MAX; " 1 2 3 only made it to condition 3
    (as suggested here)?


    Give a man a fish:  <%-{-{-{-<

      ++. I do not deny that there are multiple of fully-functional ways around the issue, and seeing so many of the TIMTOWTDI is one of the many things that draws me to PM, even though the vast bulk of my programming is not in Perl. I was pointing this out as a reasonable circumstance in which one might expect the loop variable to persist. And, like morgon expressed, it is counter-intuitive to me that my $nCond; for $nCond (1 .. 10) and my $nCond; for($nCond=1; $nCond<=10; ++$nCond) would behave differently w/r/t localization of $nCond. But every language has it's own unique character, and that's fine.

      If I needed this construct in Perl, I would have eventually settled either on my alternative or this more c-like one... But likely my own alternative: over the last couple years of regularly participating here, my mindset has changed from c-like for-loops to perlish ones, so the c-for idiom is no longer my first (or often even second) choice. And, once I was reminded of the auto-localization in foreach(), I probably would have assumed auto-localization in for(;;), and wouldn't've even tried it.

        > it is counter-intuitive to me that my $nCond; for $nCond (1 .. 10) and my $nCond; for($nCond=1; $nCond<=10; ++$nCond) would behave differently w/r/t localization of $nCond

        So meditate about it a bit more. In the

        for $var (1 .. 10)
        case, the $var is in a special position, and you can't use anything else than a scalar variable.

        The C-style for loop, on the other hand, is just a while loop in a disguise. All the three constructs in the parentheses are just expressions, i.e. you can use multiple variables there, as in

        my ($i, $j); my $k = 15; for ($i = 1, $j = 0; $i + $j < $k; $j = ++$i - rand 2) { print "$i $j\n"; }

        or you can use no variables at all

        #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; { my $var; sub init { $var = 0 } sub following { ++$var } sub exhausted { $var > 10 } sub get { $var } } for (init(); ! exhausted(); following()) { say get(); }

        So, there can't be any implicit localization, as there's nothing in general to localize.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re^3: loop surprise
by Your Mother (Archbishop) on Apr 03, 2018 at 18:30 UTC

    Okay, you make a good case. I can see that as being useful. But to my mind the loop is the scope and the for statement is the loop definition and therefore its scope. I've never felt/noticed the lack you highlight.

Re^3: loop surprise
by QM (Parson) on Apr 04, 2018 at 10:08 UTC
    I find it odd that I don't remember ever suffering from this need. I'm sure I've done something similar, but perhaps I've unconsciously soaked up that lesson long ago, and just "know" to use a second variable, or even a while loop.

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1212274]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (4)
As of 2024-04-19 04:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found