May I know what's the use of the &
in front of subs when without it, the subs are still able to run.
And also, the my
in front of perl variables.
I know it's for strict language syntax or what not, but why don't they just make it a standard that every variable needs to be declared by a my
?
EDIT
Thanks for all of your discussions/answers, I wish to accept many of your answers, but since I'm can only accept one, I will accept the one where other users might understand with ease.
In Perl, function calls have been optimized to not require the &
sigil at all times. When you declare a subroutine:
sub hello {print "world\n"}
You can call it as hello;
or hello();
or &hello();
which will all do the same thing.
If your subroutine takes arguments, it is a little different:
sub hello {print "Hello, @_!\n"}
hello 'World'; # prints 'Hello, World!'
hello('World'); # same
&hello('World'); # same
hello; # prints 'Hello, !'
&hello(); # same
&hello; # different, uses whatever was in @_ when hello was called
@_ = 'Bob';
hello; # prints 'Hello, !'
&hello(); # prints 'Hello, !'
&hello; # prints 'Hello, Bob!'
So as you can see, using the &
sigil is largely redundant, except in the case where there is no argument list. In that case, the subroutine is called with the current values in @_
.
The &
sigil also has another special behavior, related to Perl's prototypes. Say you were writing your own keys
function, and wanted it to behave like Perl's:
sub mykeys (\%) {keys %{$_[0]}}
Here the (\%)
prototype tells perl that the first argument to mykeys
must be a literal hash (which will be passed in as a hash reference).
my $hashref = {...};
say for mykeys %$hashref;
If for some reason you needed to get around this requirement (generally not the best idea), you could write this:
say for &mykeys( $hashref ); # note that there is no `%`
In this case, adding &
before the sub disables the prototype check and any subsequent actions that it would have performed (like taking the reference). In this usage, &
is basically an assertion that you know exactly what arguments mykeys
needs, and you don't want perl getting in the way.
In general, using &
on subroutines should be avoided, unless you explicitly want one of the behaviors I mentioned above.
Finally, &
is also needed when you are refering to the actual code reference:
my $coderef = \&hello;
or
if (defined &hello) {print "hello is defined\n"} # but is not called
As others have mentioned, the my
operator declares variables in the current lexical scope. It is required when the use strict;
pragma is loaded. Perl has two types of variables, lexical variables declared with my
, and package variables.
my
variables live in what is called a lexical pad, which is a storage space created by Perl each time a new scope is introduced. Package variables live in the global symbol table.
use strict;
use warnings;
$main::foo = 5; # package variable
{ # scope start
my $foo = 6;
print "$foo, $main::foo\n"; # prints '6, 5';
} # scope end
print "$foo, $main::foo\n"; # syntax error, variable $foo is not declared
You can use the our
keyword to create a lexical alias to a global variable:
use strict;
our $foo = 5; # $main::foo == $foo
{ # scope start
my $foo = 6;
print "$foo, $main::foo\n"; # prints '6, 5';
} # scope end
print "$foo, $main::foo\n"; # prints '5, 5'
# since $foo and $main::foo are the same
The my
limits the variable to the current scope. With the use strict
pragma, which you should use, you must declare the variables (e.g. with my
). The alternative to go without exists for flexibility reasons for very short scripts.
The &
is seldom used anymore since Perl default-interprets sigil-less words as subroutines, but is useful if you want to create a reference to subroutine.
sub say_hi { print "hi\n" }
my $sub_ref = \&say_hi;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With