Perl简写疑惑

use*_*649 4 perl

我从来没有真正学过Perl的任何深度,但我正在通过我的工作做一个课程(我能说"只是为了好玩吗?").我理解基础知识没有任何重大问题,但我现在正在学习参考文献和速记.我对数组的速记和访问引用值有疑问,请考虑下面的两个脚本:

  1.  

    @Codes =
            (
             ["A1W",
              ["A2Q","A2Z"]],
             ["B2R","BB3"]
            );
    $CodeRef = \@Codes;
    
    #full notation
    print @{@{@{$CodeRef}[0]}[1]}[1], "\n";
    
    #shorthand notation
    print $CodeRef->[0]->[1]->[1], "\n";
    
    Run Code Online (Sandbox Code Playgroud)
  2.  

    my $BookPageArray;
    {
            $AnotherArray = [24, 18, 36]; 
            $Reference = \$AnotherArray; 
            $BookPageArray = \$AnotherArray; 
            $AnotherArray = [53, 256, 42];  count drops to 0
    }
    undef $Reference;
    print ${$BookPageArray}->[0]."\n";
    
    Run Code Online (Sandbox Code Playgroud)

我的问题是为什么在第二个例子$BookPageArray中,最终的print语句中的引用需要在它周围使用大括号,而在第一个示例中,$ CodeRef引用不是?

如果我$在第二个例子中取出花括号和前面的符号,它告诉我该引用没有数组......

是否与第二个示例使用匿名数据这一事实有关?

Dav*_* W. 10

哇,这是可怕的代码!我知道这不是你的错.

引用通常以阵列或哈希,但$BookPageArray是一个参考参考到一个数组参考.这是炫耀还是假设教你

大括号就像数学表达式的括号一样.它们可能有助于澄清或混淆.

my $answer = 3 + 4 x 5 + 6;          # Example 1
my $answer = 3 + ( 4 x 5 ) + 6;      # Example 2
my $answer = ( 3 + 4 ) X ( 5 + 6 );  # Example 3
Run Code Online (Sandbox Code Playgroud)

实施例1和实施例2是相同的.括号是否澄清?你可以说他们这样做.在示例3中,括号是必要的.

my $answer = 1 + 3 + 4 + 9 + 10;
my $answer = ( ( ( ( 1 + 3 ) + 4 ) + 9 ) + 10 );
Run Code Online (Sandbox Code Playgroud)

同样,这些都是相同的.现在的问题是括号是否澄清是怎么回事(他们不这样做),或使它更难理解(他们这样做).

这些也是等价的:

print $foo . "\n";
print ${foo} . "\n";
Run Code Online (Sandbox Code Playgroud)

花括号在某些情况下可以提供帮助:

print "The file name is ${foo}_bar.txt\n";
Run Code Online (Sandbox Code Playgroud)

在这里,你需要为了让Perl的知道变量是花括号$foo,而不是$foo_bar.这些是等价的:

print "The file name is ${foo_bar}.txt\n";
print "The file name is $foo_bar.txt\n";
Run Code Online (Sandbox Code Playgroud)

所以,在你的陈述中你有:

${$BookPageArray}->[0]."\n";
Run Code Online (Sandbox Code Playgroud)

有些人喜欢这样,因为它有助于强调这${BookPageArray}标量参考,并帮助您看到此引用被取消引用:

${$BookPageArray}->[0]."\n";   # I see that this is a scalar reference being dereferenced
$$BookPageArray->[0]."\n";     # Didn't notice the `$$`, so missed the dereferencing.
${${$BookPageArray}}[0]."\n";  # Yes, this is the same thing!
Run Code Online (Sandbox Code Playgroud)

->当您取消引用数组和散列时,箭头语法可以帮助澄清事物.

my $value = $foo->{BAR};    # I can see that `$foo` is a reference to an array!
my $value = ${${foo}}{BAR}; # Ow! This hurts my brain
my $value = $$foo{BAR};     # Easier on the brain, but I'll miss that `$foo` is a ref.
Run Code Online (Sandbox Code Playgroud)

这些都是等价的,但第一个是最容易理解的.不幸的是,没有->相应的解除引用标量.幸运的是,它并没有经常这样做.

大多数情况下,只需完成引用即可创建复杂的数据结构:

my $person = {};  # This will be a hash reference (not necessary)...
$person->{NAME} = "Bob";
$person->{ADDR} = "123 Testing Ave.";
$person->{CITY} = "New York";
$person->{STATE} = "CA"; #Got you!
$person->{PHONE} = [];  # Array Reference (not necessary)
$person->{PHONE}->[0] = {}; # Hash reference (not necessary)
$person->{PHONE}->[0]->{TYPE} = "cell";
$person->{PHONE}->[0]->{NUMBER} = "555-1234";
Run Code Online (Sandbox Code Playgroud)

您可以在此结构中看到,我有一个人,其中包含姓名,地址和多个电话号码.

我没有要申报的东西是一个数组引用或哈希参考,但有时可以澄清你要存储什么.该my $person = {};是没有必要的.我可以做只是my $person,但它有助于澄清,这是你使用的参考.声明的电话号码数组引用大概增加了更多的烟雾比光,和不应该做的.声明为$person->{PHONE}->[0]哈希引用实际上只会减少正在发生的事情.

我建议内置的Perl参考教程.它直截了当,易于理解.我还建议你上一本好书现代的Perl,因为Perl的编码风格,并因为许多Perl书籍似乎仍然基于Perl的3.x的语法发生了变化.

在熟悉引用后,您应该阅读面向对象的Perl教程.面向对象的Perl基本上是创建一个使用引用复杂的数据结构,但在某种程度上,可以很容易跟踪复杂的结构做.

跟踪这样的事情有点复杂: $person->{PHONE}->[0]->{NUMBER} = "555-1234";


per*_*eal 5

你可以删除curlies:

$$BookPageArray->[0]."\n";
Run Code Online (Sandbox Code Playgroud)

你需要两个,$因为BookPageArray是对数组引用的引用.所以第一个'$'获取对数组的引用,箭头取消引用并索引数组.


ike*_*ami 5

注意

print @{@{@{$CodeRef}[0]}[1]}[1], "\n";  # Array slices
Run Code Online (Sandbox Code Playgroud)

应该

print ${${${$CodeRef}[0]}[1]}[1], "\n";  # Array lookups by index
Run Code Online (Sandbox Code Playgroud)

你可以在这里同样使用数组表示法.

print $CodeRef->[0]->[1]->[1], "\n";
Run Code Online (Sandbox Code Playgroud)

这简化了

print $CodeRef->[0][1][1], "\n";
Run Code Online (Sandbox Code Playgroud)

请注意此表中的相似之处.