Using ampersands and parens when calling a Perl sub
Asked Answered
T

3

14
#!/usr/bin/perl

sub t {
  print "in t\n";
  print "@_\n";
  &s;
}

sub s {
  print "in s\n";
  print "@_\n";
}

t(1,2);
print "out\n";
print "@_\n";

Output:

in t
1 2
in s
1 2
out

As you see,&s output 1 2 when no parameter is passed. Is this a feature or a bug?

Tested version is 5.8.8.

Tyrannous answered 15/7, 2011 at 12:22 Comment(1)
The real question is, is Perl a feature or a bug?Cryptanalysis
S
23

Calling a subroutine using the &NAME; syntax makes current @_ visible to it. This is documented in perlsub:

If a subroutine is called using the & form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

So, it's definitely a feature.

Shrove answered 15/7, 2011 at 12:33 Comment(2)
Worth noting also that the @_ is the SAME array as in the calling subroutine, so if the called subroutine changes @_ with shift or something like that, then the changes will be visible in @_ after the call. (which is where the efficiency comes from)Cultism
And worth noting also that using goto &mysub you can do a jump instead of a call, which means that the current stack frame is discarded, thus not wasting memory. That way you can code loops recursively, tail-recursively, to be more exact. See goto &NAME.Leprous
S
18

When using & before the sub name and no argument list is passed, the current @_ is passed as argument instead. So, it is a feature.

Here are the different ways to call a subroutine:

NAME(LIST); # & is optional with parentheses.
NAME LIST;  # Parentheses optional if predeclared/imported.
&NAME(LIST); # Circumvent prototypes.
&NAME;      # Makes current @_ visible to called subroutine.

from perldoc perlsub

Soble answered 15/7, 2011 at 12:32 Comment(4)
what do you mean by Circumvent prototypes here?Tyrannous
sub foo ($$) { }, the parens declare the prototype. The easiest thing to remember is: use name(LIST), unless you have a reason not to.Soble
I listed all the possible ways to call a sub, which is a quote from perlsub. Look it up.Soble
I think you confused yourself. The 4 things I listed was to give you an overview on how one can call a sub, and what they mean.Soble
D
2

Straight from the camel's mouth:

If a subroutine is called using the ``&'' form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

Dateless answered 15/7, 2011 at 12:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.