范围运算符的Perl上下文是什么?

时间:2014-08-07 06:33:34

标签: perl

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

use strict;
use warnings;

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

我有两个疑问。

  1. 如果表达式(10 .. 50)返回一个数组,那么,因为它是一个标量上下文," asc"应该为变量赋予数组的长度,即41。

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

  3. 但是,我得到以下的声音..

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

    感谢并欢迎任何指南。

2 个答案:

答案 0 :(得分:9)

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

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

  

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

     

...

     

如果标量的任何一个操作数" .."是一个常量表达式,如果操作数与当前输入行号(==变量)相等($.),则该操作数被视为true。

“确切”错误消息说明了正在进行的操作:

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

答案 1 :(得分:6)

  

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

     

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

您正在对一些非常不正确的误解进行操作。

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

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

Each operator决定它在每个上下文中返回的内容。有些像范围运算符(..),甚至可以根据上下文更改行为。实际上,范围运算符在标量上下文中的行为与其在列表上下文中的行为明显不同。这么多,当它在标量上下文中时,通常用不同的名称来调用它:触发器操作符。

这个问题并不是关于触发器操作员的,所以我不打算详细介绍。 (它的文档是here。)我只想说它可以用很少的代码按编号选择性地打印行。

例如,

while (<DATA>) {
   print if 2..3;
}

__DATA__
aaa
bbb
ccc
ddd
eee

输出

bbb
ccc

&#34;魔法&#34;的一部分涉及比较$.提供的数字,即最后一行读取的行号。这意味着

my $ac = 10..50;

的缩写
my $ac = ($. == 10) .. ($. == 50);

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


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