With regard to the "difference" between \(@array, @brray) and \((@array), @brray)--there is none.
In both cases, the contents of both arrays get flattened into a single list. The backslash is then applied to each element of that list. No amount of extra parens will change the outcome, which is a list of references to the elements of boths arrays.
Update: My (least) favorite gory detail is the limitation of using prototypes to create your own map-like subs that I first encountered in node 228837 and still get bitten by from time to time.
Yes, there is a difference.
\() is like a factored out reference operator before every thing inside the parenthesis, so \($foo, @bar, %baz, &frah) is (\$foo, \@bar, \%baz, \&frah), except if there's only one aggregate data type inside it. In that case it gets flattened and the backslash is then applied to each element of that list, as you say. This means that
\((@foo), @bar)
becomes
(\(@foo), \@bar)
which becomes
(\($foo[0], $foo[1], ..., $foo[$#foo]), \@bar)
and finally
((\$foo[0], \$foo[1], ..., \$foo[$#foo]), \@bar)
Another example:
\((@foo, @bar), @baz)
(\(@foo, @bar), \@baz)
((\@foo, \@bar)), \@baz)
Update: I just realized that my second example is rather useless as the end result is the same as if there was no inner parenthesis. But the intermediate step perhaps still has a pedagogical value.
(I don't know if this recursive behaviour is how it's actually performed under the hood, but it works this way none the less.)
ihb
use Data::Dumper;
@array = (1,2,3);
@brray = (4,5,6);
print Dumper [ \(@array,@brray) ];
print Dumper [ \((@array),@brray) ];
__END__
$VAR1 = [
[
1,
2,
3
],
[
4,
5,
6
]
];
$VAR1 = [
\1,
\2,
\3,
[
4,
5,
6
]
];
This is perl, v5.8.4 built for i386-linux-thread-multi
Update: oops, this should be a follow-up to [BrowserUk]'s reply...
blokhead
if ( ( $a, $b, $c ) = $current_text =~ s/$some_regex// )
{
# do something useful
next READ_MORE_DATA
}
in a parserish way. Then I have that forehead-slapping moment, and change it to this:
if ( $current_text =~ s/$some_regex// )
{
( $a, $b, $c ) = ( $1, $2, $3 );
# do something useful
next READ_MORE_DATA
}
-QM
--
Quantum Mechanics: The dreams stuff is made of
My favorite is a very general feature - the light-hearted way perl has with context. It is an annoyance to lovers of formalism that every perl builtin and function is free to return whatever it likes for the context it finds itself in. That is the essence of perl dwimmerie.
After you master the difference between list and scalar context, you get to enjoy string and numeric contexts for your values. You can savor the numification and stringification of undef.
Not only that, you get wantarray and use overload for '""', '0+' and 'bool', so you can play the game yourself!
Delicious!
After Compline,
Zaxo
Delicious!
Agreed 100%. And just a little bit of extra effort in tailoring your subs to behave intelligently pays off in terms of usabily in a huge way.
First they ignore you, then they laugh at you, then they fight you, then you win.
-- Gandhi
This isn't exactly a favourite... The fact that there's a difference between ref and ref() is... well, it simply scares me. :-) It's almost like your example, a seemlingly innocent parethesis makes a huge difference, except the behaviour in your example makes sense and is consistent.
An eof without an argument uses the last file read. Using eof() with empty parentheses is very different. It refers to the pseudo file formed from the files listed on the command line and accessed via the <> operator.
So far it doesn't seem that evil. But wait, it goes on...
Since <> isn't explicitly opened, as a normal filehandle is, an eof() before <> has been used will cause @ARGV to be examined to determine if input is available. Similarly, an eof() after <> has returned end-of-file will assume you are processing another @ARGV list, and if you haven't set @ARGV, will read input from STDIN;
That's just too much magic for one parenthesis!
ihb
Like what?
Update: to be more explicit, under -i, a simple eof() will (if needed) pull the next file(s) off of @ARGV, renaming and creating a new file for each until it gets to a non-empty one, and then selects that one as the default output file:
$ rm foo{.bak,};echo bar>foo;perl -i.bak -we'sub show { print STDOUT "files: ",
join(",", glob("*")), "\nselected: $_\n" and select $_ for select *{"TEMP"} }
show; print STDOUT eof() ? "eof\n" : "not eof\n"; show' foo
files: foo
selected: main::STDOUT
not eof
files: foo,foo.bak
selected: main::ARGVOUT
print sqrt (9) + 7; # prints 4.
print sqrt(9) + 7; # prints 10.
Abigail
$foo='hello';
for(1..5){
$foo=~/(?=(.))/g;
pos($foo)=pos($foo);
print $1
}
"The additional state of being matched with zero-length is associated with the matched string, and is reset by each assignment to pos()." |
{
my $s;
sub str :lvalue { $s }
}
str = "japhy";
pos(str) = 2;
print pos(str); # prints 2!
str =~ /\G(.)/ and print $1; # prints 'j', not 'p'
print pos(str); # prints 2!
Maybe I should perlbug this...
perlmonks.org content © perlmonks.org and Abigail-II, blokhead, BrowserUk, bunnyman, demerphq, DrHyde, Ido, ihb, japhy, QM, tilly, ysth, Zaxo, zentara
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03