Why do you need $ when accessing array and hash el

2019-01-20 08:08发布

Since arrays and hashes can only contain scalars in Perl, why do you have to use the $ to tell the interpreter that the value is a scalar when accessing array or hash elements? In other words, assuming you have an array @myarray and a hash %myhash, why do you need to do:

$x = $myarray[1];
$y = $myhash{'foo'};

instead of just doing :

$x = myarray[1];
$y = myhash{'foo'};

Why are the above ambiguous?

Wouldn't it be illegal Perl code if it was anything but a $ in that place? For example, aren't all of the following illegal in Perl?

@var[0];
@var{'key'};
%var[0];
%var{'key'};

9条回答
爷的心禁止访问
2楼-- · 2019-01-20 08:48

In Perl 5 you need the sigils ($ and @) because the default interpretation of bareword identifier is that of a subroutine call (thus eliminating the need to use & in most cases ).

查看更多
Bombasti
3楼-- · 2019-01-20 08:51

I've just used

my $x = myarray[1];

in a program and, to my surprise, here's what happened when I ran it:

$ perl foo.pl 
Flying Butt Monkeys!

That's because the whole program looks like this:

$ cat foo.pl 
#!/usr/bin/env perl

use strict;
use warnings;

sub myarray {
  print "Flying Butt Monkeys!\n";
}

my $x = myarray[1];

So myarray calls a subroutine passing it a reference to an anonymous array containing a single element, 1.

That's another reason you need the sigil on an array access.

查看更多
孤傲高冷的网名
4楼-- · 2019-01-20 08:55

The sigil give you the return type of the container. So if something starts with @, you know that it returns a list. If it starts with $, it returns a scalar.

Now if there is only an identifier after the sigil (like $foo or @foo, then it's a simple variable access. If it's followed by a [, it is an access on an array, if it's followed by a {, it's an access on a hash.

# variables
$foo
@foo

# accesses
$stuff{blubb} # accesses %stuff, returns a scalar
@stuff{@list} # accesses %stuff, returns an array
$stuff[blubb] # accesses @stuff, returns a scalar
              # (and calls the blubb() function)
@stuff[blubb] # accesses @stuff, returns an array

Some human languages have very similar concepts.

However many programmers found that confusing, so Perl 6 uses an invariant sigil.

In general the Perl 5 compiler wants to know at compile time if something is in list or in scalar context, so without the leading sigil some terms would become ambiguous.

查看更多
登录 后发表回答