【问题标题】:In Perl, is there any scenario in which ${foo[bar]} could be syntactically valid code?在 Perl 中,是否存在 ${foo[bar]} 可以是语法有效代码的情况?
【发布时间】:2012-05-17 05:27:56
【问题描述】:

我正在阅读 O'Reilly 的 Programming Perl,第 3 版,文本指出,不应使用模棱两可的搜索模式 /$foo[bar]/,而应使用 /${foo[bar]}/,这样 Perl 就不会将 [bar] 误认为一个字符类。我是否遗漏了什么,或者这两个语句在语法上都是不正确的,因为它们试图使用裸字字符串索引到数组中?我在网上查了这本书的勘误表,在书中找不到任何提到这是一个错误的地方。是否有一些我忽略了该代码可能有效的场景?

【问题讨论】:

  • 你可以把它们都放在一个程序中,看看它们是否可以编译。 perl 的 -c 开关会告诉你它们是否在语法上无效。

标签: regex arrays perl


【解决方案1】:

我正在阅读 O'Reilly 的 Programming Perl,第 3rd 版,文本指出,与其使用模棱两可的搜索模式 /$foo[bar]/,不如改为使用/${foo[bar]}/ 以便Perl 不会将[bar] 误认为是字符类。我是否遗漏了什么,或者这两个语句在语法上都是不正确的,因为它们试图使用裸字字符串对数组进行索引?

是的,你错过了一些东西:bar 可以是一个函数调用:

$ perl -Mstrict -E 'sub bar() { 0 } say "foo" =~ /$ARGV[bar]/ || "FAIL"' foo
FAIL

$ perl -Mstrict -E 'sub bar() { 0 } say "foo" =~ /${ARGV[bar]}/ || "FAIL"' foo
1

$ perl -MO=Deparse -Mstrict -E 'sub bar() { 0 } say "foo" =~ /${ARGV[bar]}/ || "FAIL"' foo
sub bar () { 0 }
use strict 'refs';
BEGIN {
    $^H{'feature_unicode'} = q(1);
    $^H{'feature_say'} = q(1);
    $^H{'feature_state'} = q(1);
    $^H{'feature_switch'} = q(1);
}
say 'foo' =~ /$ARGV[0]/ || 'FAIL';
-e syntax OK

Programming Perl, 4th edition 第 73 页的准确引用是:

在同样经过双引号插值的搜索模式中,有 是一个不幸的歧义:/$foo[bar]/ 被解释为/${foo}[bar]/ (其中[bar] 是正则表达式的字符类),或/${foo[bar]}/ (其中[bar] 是数组@foo 的下标)?如果@foo 不存在,它是 显然是一个字符类。如果@foo 存在,Perl 会很好地猜测[bar] 和 几乎总是正确的。如果它确实猜错了,或者如果你只是单纯的偏执狂, 您可以使用大括号强制正确解释,如前所示。即使 你只是谨慎,这可能不是一个坏主意。

【讨论】:

  • 我想我明白了,但是您引用的文本没有提到函数调用(此外,文本中还没有涉及函数)。当然,定义返回整数的函数以便可以使用函数名称对数组进行索引不是一个好习惯,不是吗?或者是否有一些经常出现的情况,这是有意义的?另外,你能指出我在书中的某个地方解释了以这种方式索引数组吗?
  • @clarkb86 是的,有一种情况是有意义的。当您将数组用于对象并使用各种插槽来保存不同的东西时。通常你只会使用哈希,但有时会使用数组,当它使用时,通常使用命名常量作为索引。关键是这在技术上是模棱两可的,有时您将不得不使用解决方法。我们必须在这里解释它,而不是等到我们谈论用户定义的函数,因为这里是我们谈论数组插值的地方。
  • F.e.,所有的 @_ 索引在 poe.perl.org/?POE_Cookbook/Chat_Server 中的常量
  • 说得好,但有时-le 'print 在示例中会减少分心
  • 甚至-e 'print ..., "\n"'
【解决方案2】:
sub bar { 1 }

唉,我不能单独提交;它对 SO 来说太短了。因此,这是在 Perl 中表达常量的一种方式。例如,sub MAGIC_NUMBER { 0x7774 }

【讨论】:

  • +1,但恕我直言,高级成语是use constant bar => 1;(具有相同的效果,但更明确的是bar是一个常量函数)。
  • @Alan,如果你想知道 2+2 的结果是什么,“4”是一个路过的答案。这也是的答案。如果 SO 上的每个问题和答案都是智慧书中的一页,那就太好了,但你不能通过回答未提出的问题(“什么是加法?”,“谁发明了‘加号’? ", "'2+2=1' 在多角恋社区中是什么意思?").
  • (我不得不删除我的第一条评论,我不知道那里发生了什么。)最小长度要求鼓励您考虑可能包含哪些附加信息。但请提供有用的信息。如果这个问题很简单,以至于你只能说一个路过的答案,那么可能是 question 不属于这里。 ;)
【解决方案3】:

bar 可以是一个函数:

perl -le 'sub bar () { 1 } my @foo = qw(hello world); print m/${foo[bar]}/ ? "$_ -> TRUE" : "$_ -> FALSE" for qw(hello world)'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多