Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

apparent strangeness using subroutine with the multiplication operator

Tags:

perl

Please could you explain this *apparently* inconsistent behaviour to me:

use strict;
sub a { 2 + 2 };
print 2 * a(); # this prints: 8
print a() * 2; # this prints: 8
print 2 * a;   # this prints: 8
print a * 2;   # this prints: 4

Thanks for answers, both very helpful - I learned a lot.

like image 372
Literat Avatar asked Dec 03 '22 03:12

Literat


2 Answers

Deparse reveals that you are passing a glob to a in the last one:

$ perl -MO=Deparse,-p
use strict;
sub a { 2 + 2 };
print 2 * a(); # this prints: 8
print a() * 2; # this prints: 8
print 2 * a; # this prints: 8
print a * 2; # this prints: 4
__END__
sub a {
    use strict 'refs';
    4;
}
use strict 'refs';
print((2 * a()));
print((a() * 2));
print((2 * a()));
print(a(*2));

Using parens on your subroutine calls is a good thing...

like image 129
ysth Avatar answered Dec 18 '22 12:12

ysth


In the last example, the expression is parsed as a(*2) which calls a with the glob argument *2 which is the short name of the package variable *main::2

If you want a to be parsed as a function that takes no arguments, you need to declare it like this:

sub a () {2 + 2}

Then perl will parse the statement as you expected. In fact, if you write it like this, perl will detect that it is a constant function, and will inline 4 in every place where a would have been called.

like image 30
Eric Strom Avatar answered Dec 18 '22 11:12

Eric Strom