Protip: you should stay on list for this. :) Cc'ing the list.

On Sun, Mar 10, 2013 at 11:16:50AM +0000, John Delacour wrote:
> On 09/03/2013 20:57, Brandon McCaig wrote:
> >You cannot have anonymous arrays in Perl except by reference.
> 
> What about this?
> 
> for (split //, "abc") {
>     print "$_\n";
> }

There is no array here. There are only lists. See perldoc
perldata.

>  List value constructors
>       List values are denoted by separating individual values
>       by commas (and enclosing the list in parentheses where
>       precedence requires it):
> 
>           (LIST)
> 
>       In a context not requiring a list value, the value of
>       what appears to be a list literal is simply the value of
>       the final element, as with the C comma operator.  For
>       example,
> 
>           @foo = ('cc', '-E', $bar);
> 
>       assigns the entire list value to array @foo, but
> 
>           $foo = ('cc', '-E', $bar);
> 
>       assigns the value of variable $bar to the scalar variable
>       $foo.  Note that the value of an actual array in scalar
>       context is the length of the array; the following assigns
>       the value 3 to $foo:
> 
>           @foo = ('cc', '-E', $bar);
>           $foo = @foo;                # $foo gets 3

I'm not sure exactly where list values are explained (I think
it is explained more directly than this, but this is what I could
find at the moment).

If you read through the docs you will discover that subroutine
arguments and return values are expanded into lists automatically
(exact semantics may be altered by prototypes or built-in
semantics). Thus, in your example above you passed split
/PATTERN/ and /EXPR/ (split is built-in and its semantics are not
the same as user-defined functions), and in exchange split
returned a list of ('a', 'b', 'c'), which your for-loop then
iterated over. At no point was an actual array allocated for this
data.

For example:

  @bar = (1,2,3);
  foo(@bar);

It may look like you are passing foo an array, but really you are
passing foo a list of values (which are "aliased").

  sub foo {
      # The list passed to foo is in @_.

      $_[0]++; # Here we can increment the caller's @bar[0]
               # because arguments are always aliased in Perl.
               # (Note: you generally /shouldn't/ do this)

      unshift @_, '0'; # However, modifying @_ doesn't affect
                       # the caller's @bar in any way. They are
                       # not the same array.
  }

For an actual executable example:

#!/usr/bin/perl

use strict; # Should always use strict and warnings.
use warnings;

use Data::Dumper;

main();

sub main {
    my @bar = (1,2,3);

    print q/Before: main's @bar is: /, Dumper \@bar;

    foo(@bar);

    print q/After: main's @bar is: /, Dumper \@bar;
}

sub foo {
    print q/Before: foo's @_ is: /, Dumper \@_;

    $_[0]++;
    unshift @_, 0;

    print q/After: foo's @_ is: /, Dumper \@_;
}

__END__

Output:

Before: main's @bar is: $VAR1 = [
          1,
          2,
          3
        ];
Before: foo's @_ is: $VAR1 = [
          1,
          2,
          3
        ];
After: foo's @_ is: $VAR1 = [
          0,
          2,
          2,
          3
        ];
After: main's @bar is: $VAR1 = [
          2,
          2,
          3
        ];

Notice that $bar[0] is modified, but @bar itself could not be
(i.e., more elements couldn't be added from within foo).

The thing for for-loops to iterate is also a list, so if you say:

  for (@bar) { ... }

You are really saying to expand @bar into a list and iterate over
that. Which is why you can also directly loop over a hash (though
it's generally less meaningful to do so):

  for (%baz) { ... }

The first iteration will be the first key (which isn't
necessarily the first key/value pair you stored), the second will
be the value stored in the hash by that key, the third will be
the second key, the forth its value, etc.

And of course, you can just pass a list value instead:

  for (1,2,3) { ... }

Regards,


-- 
Brandon McCaig <bamcc...@gmail.com> <bamcc...@castopulence.org>
Castopulence Software <https://www.castopulence.org/>
Blog <http://www.bamccaig.com/>
perl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }.
q{Vg qbrfa'\''g nyjnlf fbhaq gung jnl.};
tr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'

Attachment: signature.asc
Description: Digital signature

Reply via email to