Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Re: Different result for 'foreach' vs 'while shift' arrayref

by tobyink (Abbot)
on Apr 18, 2014 at 09:17 UTC ( #1082734=note: print w/replies, xml ) Need Help??

in reply to Different result for 'foreach' vs 'while shift' arrayref

With this one:

while (my $result = shift(@$rowcache) )

If @$rowcache contains a false value (e.g. undef, or the empty string, or the number 0), then when that value is reached, the condition will become false, so the while loop will exit.

If you really want to use while, then you could do:

while (my ($result) = @$rowcache ? shift(@$rowcache) : ())

Or, if you know that @$rowcache consists of only defined values (no undefs, but perhaps some empty strings and zeros), you could do:

while ( defined(my $result = shift @$rowcache) )
use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Replies are listed 'Best First'.
Re^2: Different result for 'foreach' vs 'while shift' arrayref
by Your Mother (Chancellor) on Apr 18, 2014 at 23:57 UTC

    And I think this, while breaking the mental encapsulation of the single line versions, might be easier for some hackers to grok. No personal preference here; just tossing one more on the pile.

    while ( @{$rowcache} ) { my $result = shift @{$rowcache}; ....

      That's certainly true. I often use that, and have no idea why I didn't suggest it myself!

      Generally speaking the reason to use this idiom is when you need to loop through a list and in each iteration you need to take one or more items from the list.This kind of thing:

      use strict; use warnings; use Data::Dumper; my @input = ( 'foo:' => 1, 'bar:' => 2, 'baz', # no colon, so value is "1" 'quux:' => 3, ); my %output; while (@input) { my $key = shift @input; if ($key =~ /\A(.+):\z/) { $output{$1} = shift @input; } else { $output{$key} = 1; } } print Dumper \%output;

      If you only need to step through the list one at a time, use foreach; it's clearer.

      use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1082734]
[choroba]: Algorithm::Loops
[Corion]: choroba: I'm using that to generate the permutations, but I don't know how the user can pass the intended values to my function in a sane way
[Corion]: I have a prototype that permutes the get_parameters, but the values used for the get parameters should be different from the values used for the headers and potentially for parts of the URL
[Corion]: But yes, in general, my approach will be "split the URL into another set of parameters, generate an array of allowed values for each parameter and then NestedLoops() over the set"
[choroba]: hmm... so you need something like bag from Test::Deep, but not for checking, but for generation
[Corion]: This has the dual use of easily requesting sequential URLs and also being suitable for testing
[Corion]: For testing, I want to skip all tests with the same value(s) once one test fails to cut down on the number of failing tests
[Corion]: choroba: Yes, in a way I
[Corion]: ... I'm treating the incoming value sets as bags... Maybe I'll just put the burden on the user, at least in the first attempt at a full API. generate( headers => [{ 'Content-Type' => 'text/plain' }, {'Content-Type' => 'text/json' ] ), even ...
[Corion]: ... if that is cumbersome for the caller to specify. On the other hand, maybe there isn't that big a need for permuting the header values

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (5)
As of 2017-01-17 08:22 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (152 votes). Check out past polls.