Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Perl method call without parentheses

One of my projects contain a lot of simple method calls. I would like to call them without parenthesis to avoid clutter and make frequent modifications easier.

I did the following tests.

With parentheses (obviously works):

my $something = [1, 2, 3];

my $dumper = Data::Dumper->new([$something]);

$dumper->Indent(0);

say $dumper->Dump();

Now without parenthesis (only works for methods without parameters)

my $something = [1, 2, 3];

# my $dumper = Data::Dumper->new [$something];  # syntax error
my $dumper = Data::Dumper->new([$something]);

# $dumper->Indent 0; # Number found where operator expected
$dumper->Indent(0);

say $dumper->Dump;  # works!

I also tested indirect syntax. I know about its problems, but if it would work it could be an option. But it doesn't.

sub say2 { say @_; return; }

my $something = [1, 2, 3];

my $dumper = new Data::Dumper [$something]; # works!

# Indent $dumper, 0; # No error, but doesn't do what supposed to happen
Indent $dumper(0); # works

# say Dump $dumper;  # say() on unopened filehandle Dump
say2 Dump $dumper;  # works

Is there a way to call methods consistently without parenthesis? I don't see a real reason why Perl wouldn't allow it because there doesn't seem to be any ambiguity. For subs we have "use subs", perhaps something similar exists for methods?

And for completeness, is there a way to avoid the 'say2' sub in the above example and still call without parentheses?

Perhaps there is some sort of hack or trick possible?

like image 372
barney765 Avatar asked Oct 16 '14 13:10

barney765


1 Answers

What I think we're talking about here is prototyping - you can specify a prototype for a subroutine, which shows what arguments - and types - it's expecting. If you don't prototype, perl has to guess what types arguments are and how to use them.

It doesn't always get this right - so in your example, if you:

 say Dump $dumper; 

Perl doesn't know whether say is getting two arguments or one. It has to guess, and doesn't always guess correctly. say in particular is actually fairly complicated in what it can take, because you can give it an array of things to print. But you can also give it a file handle to print to - the way it tells the difference is via a prototype.

Single argument subroutines it's usually pretty obvious you've got sub and argument, but anything else is potentially ambiguous.

But as the perldoc perlsub says:

"Method calls are not influenced by prototypes either, because the function to be called is indeterminate at compile time, since the exact code called depends on inheritance"

So the short answer is - you can't do it, just use the parentheses.

like image 113
Sobrique Avatar answered Sep 21 '22 04:09

Sobrique