ForeverLearning has asked for the wisdom of the Perl Monks concerning the following question:

Having a bit of a "dumb" moment here, can't figure out why this isn't working !

The result I get is :
4194304
8388608

The expected result is :
0
4194304
8388608

Here is my test case code:

#!/usr/bin/perl use 5.014; use strict; use warnings; use autodie; my @arrX = (0,4194304,8388608); my $count = 0; my $max = 3; sub sendX { return if $count >= $max; my $data = shift @arrX; return if not $data; $count++; say $data; } for (1 .. $max) { sendX; }

Replies are listed 'Best First'.
Re: "shift" not working as expected
by LanX (Saint) on Mar 20, 2016 at 15:45 UTC
    This ...

    > The expected result is : 0

    ... and this ...

    > return if not $data;

    ... collide, because 0 is false in Perl.

    You want to try defined or even better just check the size of @arrX °

    BTW: This code looks weird, what's your real intention?

    HTH! =)

    Cheers Rolf
    (addicted to the Perl Programming Language and ☆☆☆☆ :)
    Je suis Charlie!

    update

    °)... e.g. like in return unless @arrX

    ... which is very Perlish, boolean context is subcase of scalar context which returns the size.

    And as we know now that 0 is false ;-)

      Hi Lanx,

      Thanks for your reply. Regarding my "weird code", the underlying concept is the "Throttle" example from this AnyEvent::HTTP tutorial (http://perlmaven.com/fetching-several-web-pages-in-parallel-using-anyevent).

      If you think that way of doing things is weird, do let me know ! I don't want to do weird stuff that might come and bite me in the backside later !

      Perhaps to clarify my "real intention" even further than my previous reply, I'm planning to loop through an array of offset counts so that I can use AnyHTTP to upload blocks of a large file to a REST API in parrallel.
        Unfortunately I'm not qualified to talk about AnyEvent et. al.

        Your code looked strange because of all the closures, but in the case of defining simultaneous call backs this looks like the way to go. :)

        Cheers Rolf
        (addicted to the Perl Programming Language and ☆☆☆☆ :)
        Je suis Charlie!

Re: "shift" not working as expected
by Anonymous Monk on Mar 20, 2016 at 15:47 UTC
Re: "shift" not working as expected
by flexvault (Monsignor) on Mar 20, 2016 at 16:40 UTC

    ForeverLearning,

    Forget about this answer, looked again, and I'm wrong! Not enough coffee yet!

    This:

    for (1 .. $max) { sendX; }
    should be:
    for (0 .. $max) { sendX; }
    whether or not your 'sub sendX' is correct!

    Regards...Ed

    "Well done is better than well said." - Benjamin Franklin

      I think the key thing is the use of "if not defined" instead of a numeric/Boolean comparison. A 0 or 1 start for loop doesn't matter (0,1,2,3) or (1,2,3), and actually $count and $max in the sub() don't really either as far as the sub is concerned except that those factors limit the number of times the sub is called in the for() loop. In the OP's code using 1..$max calls the sub 3 times, using 0..$max calls it 4 times.

      #!/usr/bin/perl use 5.014; use strict; use warnings; use autodie; my @arrX = (0,4194304,8388608); my $count = 0; #makes no difference in sub my $max = 300; #makes no difference in sub sub sendX { my ($data) = shift @arrX; return if not defined $data; # use defined, not numeric/boolea +n say $data; } for (1 .. $max) { #could be 1 .. scalar(@arrX)??? sendX; } __END__ Prints: 0 4194304 8388608
      I am also a bit mystified as to how this relates to some purpose.