Reputation: 1507
AFAIK, parenthesis in perl are for:
so,
my $r = ($x+$y) * $z;
my(@l) = (1,2,3);
What is a meaning of a parenthesis in a function call? I didn't find any, the sub will get a simple list of its arguments.
#!/usr/bin/env perl
use Modern::Perl;
use Data::Dumper;
sub xxx { say Dumper \@_ }
xxx( 1, 2, 3 );
xxx( 1, (2, 3) );
xxx 1, (2, 3) ;
xxx 1, 2, 3;
right?
Asking because the perl -MO=Deparse
didn't remove the parenthesis from the function calls.
so for the next short script
use Moose;
has 'arg' => (is=>'rw', isa=>'Str');
returns
has('arg', ('is', 'rw', 'isa', 'Str'));
and not the simple
has('arg', 'is', 'rw', 'isa', 'Str');
Is here any difference?
Upvotes: 3
Views: 337
Reputation: 57600
When the parens are not removed by deparsing, this is because they can be used to determine precedence. The snippets has('arg', 'is', 'rw', 'isa', 'Str')
and has('arg', ('is', 'rw', 'isa', 'Str'))
produce different Opcodes (although in this case the difference could be removed safely).
Parens do not create lists. “Lists” in Perl are not distinct data structures. They are just a more accessible description of a stack segment. If anything would create a list, then it would be the comma operator ,
in list context. (But it doesn't as there are no lists).
If the subroutine you are calling is known at parse time, then the parens from a function invocation are optional, i.e. the syntax is either any_function(@args)
or known_function @args
. Known functions can also use prototypes to change how the arguments are parsed (regardless of whether parens where used). For known functions it is not relevant whether the deparsed call uses parens, or not: both produce the same Opcodes.
Upvotes: 2
Reputation: 13664
In your examples, an exception to "they're all the same" would be something like this:
xxx (1,2), 3;
The difference between the following:
has('arg', ('is', 'rw', 'isa', 'Str'));
has('arg', 'is', 'rw', 'isa', 'Str');
is that the former builds one list, then builds a second list, pushing the first list onto it. The latter builds everything as a single list. You can see the difference using B::Concise; they compile to slightly different op trees. The former example will run ever so slightly slower, but there's little difference in it.
use strict;
use warnings;
use Benchmark qw(cmpthese);
cmpthese(-5, {
once => q[ my @x = (foo => (bar => 1, baz => 2)) ],
twice => q[ my @x = (foo => bar => 1, baz => 2 ) ],
});
__END__
Rate twice once
twice 216835/s -- -1%
once 218228/s 1% --
Upvotes: 3