印記
Perl 有許多符號:
$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry
這些看起來像 sigils,但不是:
\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array
如果你願意,可以在 sigil 之後使用牙套。偶爾,這會提高可讀性。
say ${value} = 5;
當你使用不同的符號來定義不同型別的變數時,可以根據你使用的符號以不同的方式訪問相同的變數。
%hash; # we use % because we are looking at an entire hash
$hash{it}; # we want a single value, however, that's singular, so we use $
$array[0]; # likewise for an array. notice the change in brackets.
@array[0,3]; # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
# (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')
對於參考文獻尤其如此。為了使用引用值,你可以將符號組合在一起。
my @array = 1..5; # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6; # push expects an array
push @$reference_to_an_array, 7; # the @ sigil means what's on the right is an array
# and what's on the right is $reference_to_an_array
# hence: first a @, then a $
這是一個可能不那麼容易混淆的思考方式。正如我們之前看到的,你可以使用大括號來包裹 sigil 右側的內容。因此,你可以將 @{}
視為採用陣列引用併為你提供引用陣列的內容。
# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!
事實證明,@{}
實際上接受了一個表示式:
my $values = undef;
say pop @{ $values }; # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5
……同樣的伎倆也適用於其他符號。
# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
"This doesn't crash";
}
…但是如果對於印記的論證很簡單,你可以把括號留下來。
say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };
事情可能變得過於奢侈。這是有效的,但請 Perl 負責任地。
my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;
my $italian = $hash{it}; # Direct access
my @greets = @$reference{'it', 'en'}; # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash
對於大多數正常使用,你只需使用沒有印記的子程式名稱。 (沒有 sigil 的變數通常被稱為 barewords
。)&
sigil 僅在有限數量的情況下有用。
-
引用子例程:
sub many_bars { 'bar' x $_[0] } my $reference = \&many_bars; say $reference->(3); # barbarbar
-
呼叫函式忽略其原型。
-
結合 goto,作為一個稍微奇怪的函式呼叫,將當前呼叫框架替換為呼叫者。想想 linux
exec()
API 呼叫,但是對於函式。