【问题标题】:Perl's foreach with string argumentPerl 带字符串参数的 foreach
【发布时间】:2019-02-05 02:28:54
【问题描述】:

Perldocs 仅表明 foreach 循环“迭代普通列表值”https://perldoc.perl.org/perlsyn.html#Foreach-Loops,但我有时会看到它们带有字符串参数,例如以下示例:

foreach (`curl example.com 2>/dev/null`) {
    # iterates 50 times
}

foreach ("foo\nbar\nbaz") {
    # iterates just 1 time. Why?
}

是否定义了传递这样一个字符串的行为?另外,为什么像示例中那样传递反引号命令返回的字符串和文字字符串会产生不同的结果?

【问题讨论】:

  • for (split /^/m, $file_contents) 会得到你想要的

标签: perl


【解决方案1】:

在标量上下文中,反引号返回单个标量,其中包含封闭命令的所有输出。但是foreach (...) 在列表上下文中计算反引号,这会将输出分成一个列表,每个元素一行。

【讨论】:

    【解决方案2】:

    问题围绕着context,这是 Perl 中许多事物的关键概念。

    foreach 循环需要一个列表来迭代,因此它会强制使用列表上下文来构建您在文档中看到的list values。该列表可以由文字qw(a b c) 组成,并且可以有一个元素;这是您的第二个示例,其中给出了一个字符串,形成迭代的单元素列表。

    列表也可以来自于在列表上下文中计算的表达式;这是你的第一个例子。许多操作会根据上下文产生不同的返回,qx 就是这样一个操作符,正如 mob 的回答中所解释的那样。这是需要注意和小心的。无论上下文如何,表达式也可以返回单个值;那么它只是用于填充列表。

    【讨论】:

    • 谢谢,这是我的困惑。我对 Perl 如何强制执行上下文有一些过于简单的假设。
    • 参见。 print join ":", localtimeprint join ":", scalar localtime 甚至 print join ":", sub{wantarray ? (1,2,3) : "scalar" }->()
    【解决方案3】:

    来自perldoc -f qx

    在列表上下文中,返回行列表(但是您已使用 $/ 或 $INPUT_RECORD_SEPARATOR 定义行),如果命令失败,则返回空列表。

    来自perldoc perlsyn

    复合语句

    [...]

    标签 foreach VAR(列表)块

    【讨论】:

      【解决方案4】:

      字符串不是列表。如果你想遍历字符串中的字符,你需要

      foreach my $character (split('', "foo\nbar\nbaz")) {
      

      我认为您可能会将 Perl 与 Python 混淆:

      >>> for c in "foo\nbar\nbaz":
      ...    print c
      ... 
      f
      o
      .... remainder deleted ....
      a
      z
      >>>
      

      正如其他答案所指出的那样,反引号/qx{} 在列表上下文中返回已执行命令的输出行列表。

      【讨论】:

      • foreach ("foo") { ... } 是完全有效的 Perl,循环遍历单个元素列表 ("foo")
      猜你喜欢
      • 1970-01-01
      • 2021-10-07
      • 2019-11-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-03
      • 1970-01-01
      • 1970-01-01
      • 2022-06-28
      相关资源
      最近更新 更多