Perl速记疑惑

标签 perl

我从来没有真正深入地学习过 Perl,但我正在通过我的工作学习一门类(class)(我可以说“只是为了好玩”?)。
我了解基础知识,没有任何大问题,但现在正在学习引用资料和速记。我对数组的简写和访问引用值有疑问,请考虑以下两个脚本:


  • @Codes =
            (
             ["A1W",
              ["A2Q","A2Z"]],
             ["B2R","BB3"]
            );
    $CodeRef = \@Codes;
    
    #full notation
    print @{@{@{$CodeRef}[0]}[1]}[1], "\n";
    
    #shorthand notation
    print $CodeRef->[0]->[1]->[1], "\n";
    

  • my $BookPageArray;
    {
            $AnotherArray = [24, 18, 36]; 
            $Reference = \$AnotherArray; 
            $BookPageArray = \$AnotherArray; 
            $AnotherArray = [53, 256, 42];  count drops to 0
    }
    undef $Reference;
    print ${$BookPageArray}->[0]."\n";
    

  • 我的问题是为什么在第二个例子中 $BookPageArray最终打印语句中的引用需要用大括号括起来,而在第一个示例中,$CodeRef 引用不需要?

    如果我去掉大括号和前面的 $登录第二个示例,它告诉我该引用处没有数组...

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

    最佳答案

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

    引用通常是数组或散列,但 $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
    

    例1和例2相同。括号解释清楚了吗?你可以争辩说他们这样做。在示例 3 中,括号是必需的。
    my $answer = 1 + 3 + 4 + 9 + 10;
    my $answer = ( ( ( ( 1 + 3 ) + 4 ) + 9 ) + 10 );
    

    同样,这两者是相同的。问题是括号是澄清了正在发生的事情(他们没有)还是让它更难理解(他们做了)。

    这些也是等价的:
    print $foo . "\n";
    print ${foo} . "\n";
    

    花括号在某些情况下可以提供帮助:
    print "The file name is ${foo}_bar.txt\n";
    

    在这里,你需要花括号让 Perl 知道变量是 $foo而不是 $foo_bar .这些是等效的:
    print "The file name is ${foo_bar}.txt\n";
    print "The file name is $foo_bar.txt\n";
    

    所以,在你的陈述中,你有:
    ${$BookPageArray}->[0]."\n";
    

    有些人喜欢这样,因为它有助于强调${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!
    

    箭头 ->当您取消引用数组和散列时,语法可以帮助澄清事情。
    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.
    

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

    大多数时候,引用只是为了创建复杂的数据结构:
    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";
    

    你可以在这个结构中看到,我有一个人有姓名、地​​址和多个电话号码。

    我不必将某些内容声明为数组引用或散列引用,但它有时可以阐明您存储的内容。 my $person = {};没有必要。我本来可以做的my $person ,但它有助于澄清它是您正在使用的引用。为电话号码声明数组引用可能会增加烟雾而不是光,并且不应该这样做。声明$person->{PHONE}->[0]成为散列引用实际上只会减损正在发生的事情。

    我建议内置 Perl reference tutorial .它很直接,很容易理解。我还建议你在 Modern Perl 上买一本好书由于 Perl 的编码风格和语法自 Perl 3.x 以来发生了变化,许多 Perl 书籍似乎仍然基于这些。

    在熟悉引用文献后,您应该阅读 Object Oriented Perl tutorial .面向对象的 Perl 基本上是使用引用创建复杂的数据结构,但以一种易于跟踪复杂结构的方式进行。

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

    关于Perl速记疑惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19813630/

    相关文章:

    regex - 提取短语后的所有文本,然后在每行的开头添加文件名?

    GetWindowPlacement 处的 Perl Win32::API 缓冲区溢出

    regex - 使用正则表达式解析许可证文件

    regex - 如何处理 Perl 正则表达式中的特殊字符?

    perl - 浅拷贝引用到 Perl 中的变量

    regex - 如何使用 REGEX perl 提取两个模式之间的文本

    perl - 有人可以解释这个混淆的 perl regexp 脚本吗?

    perl - 如何批量搜索并替换为Perl?

    perl - 从 CPAN 安装模块时无法识别 dmake 命令

    perl - 解析 html 文件以便稍后将其输入数据库的最简单方法是什么?