ok, what's going on here is the following:

map 'maps' (returns to whatever is on the left hand side of it) the return
value of whatever is in between the { } after the 'map' statement;

so if you say:

    my @foo = qw(bar baz);
    my @bar = map { s/a/e/ } @foo;
    print @bar;

that will print '11' (two 1's, one for every return value of s/// which is
'1' on a succesfull substitution)
what we wanted however, is 'ber' and 'bez' to be in @bar, not the return
value of s///.
not a problem; we just have to tell map that it should return 'ber' and
'bez' instead... which are conveniently held in $_ So to get done what we
want, we need to write:

    my @foo = qw(bar baz);
    my @bar = map { s/a/e/; $_ } @foo;
    print @bar;

now map will return $_, rather then the return value of s///
the above is equivalent to the more verbose:

    my @foo = qw(bar baz);
    my @bar = map { my $baz = $_; $baz =~ s/a/e/; $baz } @foo;
    print @bar;

The use of the local operator is as described below adds little
functionality other then readabillity, seeing how the map function is in { }
meaning that $_ is local to the function anyway.
concider the following:

    $_ = 'blech';
    my @foo = qw(bar baz);
    my @bar = map { s/a/e/; $_ } @foo;
    print @bar;
    print;

the above will print "berbezblech", thanks to the implicit localising thru
the map's { }

hope this helps,

Jos Boumans



> > > [using map to transform an old array to a new array
> > >  leaving the old one unchanged?]
> >
> > Here's my best shot:
> >
> >     map { my $foo = $_; $foo =~ s/qux/waldo/ and $foo } @bar;
>
> Fwiw, I just thought of a more brief and elegant way:
>
>     @newarray = map { local $_ = $_; s/foo/bar/; $_ } @oldarray;
>
>

Reply via email to