开发者

Perl syntax sigil

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 per开发者_开发技巧l 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;


May I know what's the use of the & in front of subs when without it, the subs are still able to run.

Backwards compatibility with Perl 4

And also, the my in front of perl variables.

It sets block scope

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?

  1. Backwards compatibility (hence use strict; disallowing bare variable declarations)
  2. Variables can also be declared with our or local


If you want to know how to write modern Perl, may I recommend you read Modern Perl? You can buy a dead tree version or download an electronic version for free.


& has still pretty good distinction: calling with it (&YourSub) makes current @_ visible to called sub too. Anyway, i use it in my scripts mostly for clarity reasons: it makes clear, which are my own functions and which functions from core or modules.

About my. Every tutorial and doc suggest to use use strict; pragma, so you have then declare your varaible with my too. So, the situation from my point of view is pretty backwards: if scope is so important for best practicies, it would be normal that variables are scoped by default (like we say with my now) and when we really need global variables, we should declare them as that. I understand it is perl's legacy, but still it is against Perl's ideology to keep out redundancy. Using my every time for declaring could be overridden by some sort of pragma. [Sorry, robobooga, maybe going too far from your question]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜