【问题标题】:What is the Perl context with range operator?范围运算符的 Perl 上下文是什么?
【发布时间】:2014-09-30 06:57:18
【问题描述】:

我是 Perl 新手。我想结合范围运算符来理解 Perl 上下文。这是我的代码。

use strict;
use warnings;

my $asc = ( 10 .. 50 );
print "$asc\n";

我有两个疑问。

  1. 如果表达式 (10 .. 50) 返回一个数组,那么,由于它是一个标量上下文,“asc”变量应该被分配数组的长度,即 41。

  2. 如果表达式 ( 10 ..50 ) 返回一个列表,那么,由于它是一个标量上下文,“asc”变量应该分配给列表中的最后一项,即 50。

但是,我听到了下面的喊声..

Use of uninitialized value in range (or flip) at main.pl line ..

感谢并欢迎任何指南。

【问题讨论】:

    标签: perl


    【解决方案1】:

    您在标量上下文中使用Range Operator ..,这也称为触发器运算符。

    您应该阅读整个文档,但以下摘录与您的情况相关:

    在标量上下文中,“..”返回一个布尔值。该运算符是双稳态的,类似于 触发器,并模拟 sed、awk 和各种编辑器的行范围(逗号)运算符。

    ...

    如果标量“..”的任一操作数是常量表达式,则如果该操作数等于(==)当前输入行号($. 变量),则认为该操作数为真。

    “确切”错误消息解释了发生了什么:

    Use of uninitialized value $. in range (or flip)
    

    基本上,Perl 将此用法解释为触发器测试。

    它正在测试当前行号$.是否等于您指定的整数值:

    my $asc = ( $. == 10 .. $. == 50 );
    

    但是,由于您尚未从文件句柄中读取,$. 变量未初始化并引发警告。

    实现列表上下文

    可以获得您描述的列表上下文行为,但您需要调整代码以使您的意图更加明确:

    my $count = () = (10..50);          # Forces a list context
    my $last_element = (10..50)[-1];    # Also forces a list context
    
    print "$count\n";
    print "$last_element\n";
    

    输出:

    41
    50
    

    【讨论】:

      【解决方案2】:

      如果表达式 (10 .. 50) 返回一个数组,那么,由于它是一个标量上下文,...

      如果表达式 (10 ..50) 返回一个列表,那么,由于它是一个标量上下文,...

      你在操作一些非常不正确的误解。

      • 不可能返回一个数组[1]。唯一可以返回的是零个或多个标量。在标量上下文中,该列表的长度必须正好是一个标量。

      • 标量上下文导致操作符改变它返回的内容;它不会导致返回的值被强制转换为标量。

      Each operator 决定它在每个上下文中返回的内容。有些,比如范围运算符 (..),甚至会根据上下文改变行为。事实上,范围运算符在标量上下文中的行为与其在列表上下文中的行为有很大不同。如此之多,当它在标量上下文中时,它通常被称为不同的名称:触发器运算符。

      这个问题并不是关于触发器操作符的,所以我不打算详细说明。 (它的文档是here。)只要说它可以用很少的代码有选择地按数字打印行就足够了。

      例如,

      while (<DATA>) {
         print if 2..3;
      }
      
      __DATA__
      aaa
      bbb
      ccc
      ddd
      eee
      

      输出

      bbb
      ccc
      

      “魔术”的一部分涉及将提供的数字与$.(最后读取的行号)进行比较。这意味着

      my $ac = 10..50;
      

      简称

      my $ac = ($. == 10) .. ($. == 50);
      

      由于您从未从文件中读取,$. 未定义。


      1. 当您执行return @array; 时,您可以根据上下文返回数组元素 ($array[0], $array[1], ...) 或其长度。

      【讨论】:

        猜你喜欢
        • 2019-02-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-29
        • 2011-02-23
        • 2011-04-05
        相关资源
        最近更新 更多