in reply to using shift and $_ in loop

I'm not sure that what you want to do is sane, but that might be because I don't know your purpose. The following works but leaves @_ unmodified until after your loop:

sub scribble { for (@_) { ... }; @_ = (); };

Alternatively, with the assignment:

sub scribble { while ($_ = shift) { ... }; };

My second approach and your while(...) approach suffer from the same problem that they will end the loop if a false value is contained in @_

Replies are listed 'Best First'.
Re^2: using shift and $_ in loop
by leocharre (Priest) on Oct 21, 2009 at 15:50 UTC
    Yes they do suffer that- it tests for truth.

    Maybe I was too vague in my posting, if so I apologize.

    I expect my sub to take an unforeseen number of arguments. My sub will take the arguments, discard some, and the ones that are not discarded, will be altered- and a list of the altered arguments are returned back.

    An example..

    use Lingua::Names 'is_name'; my @a = qw/andy lo1 beca cris/; my @A = alter(@a); sub alter { my @newlist; for ( @_ ){ my $name = is_name($_) or next; push @newlist, uc($name); } @newlist; }

    Now, how can I make this so I can use shift, maybe even a for loop with undef and last??? What might be apropriate here to make it a little more minimal? This is a little closer..

    sub alter { my @newlist; while ( @_ ){ $_ = shift @_; my $name = is_name($_) or next; push @newlist, uc($name); } @newlist; }
    I'm wondering if I can just shift and push from @_ and then return the modified @_ .. using $_ ??? Maybe this is just too much coffee speaking and I need to chill out?
      sub alter { my @newlist; for ( @_ ){ my $name = is_name($_) or next; push @newlist, uc($name); } @newlist; }

      I'd write that as

      sub alter { grep $_, map { uc is_name($_) } @_; }

      instead.

      In Perl 6 I'd maybe write something more similar to what you wrote:

      sub alter(*@a) { gather for @a { my $name = is_name($_); take uc $name if $name; } }

      Or even

      sub alter(*@a) { gather for @a.map({ is_name($_)}) { take .uc if $_; } }
      Perl 6 - links to (nearly) everything that is Perl 6.
        Are you going around tempting people to use perl6? I've looked at some specs.. pretty freaking interesting- a little scary too. Like "defined or" .. //= very sexy.. I wonder is all this stuff I'm looking at here actually implemented? Wild.

      Now, how can I make this so I can use shift,

      What's wrong with the for version?

      map and grep lend themselves well here:

      sub alter { return map uc, grep is_name($_), @_; }
      If I'm reading this correctly, you want @A as the elements of @a that pass the is_name(x) test?
      @A = grep { is_name($_) } @a;
      perldoc -f grep is your friend.

      Update: I just noticed the uc() you used. In that case:

      @A = map { uc($_) } grep { is_name($_) } @a;
      perldoc -f map is also your friend.

        Both of your examples use the return value of is_name($_) only for truth testing, but it should (after applying uc) be assembled in the result array, at least that's what the OP's example does (don't know if it makes sense)

        Perl 6 - links to (nearly) everything that is Perl 6.