#!/usr/bin/perl
use Modern::Perl;
while (<>)
{ chomp;
say reverse;
}
以上代码不起作用,但当我将第二行最后一行更改为say scalar reverse;
时,它可以正常工作。为什么我需要强制它明确地成为标量?不能Perl DWIM?
答案 0 :(得分:6)
如果我理解文档正确,reverse
通常在列表上运行。在不带参数的列表上下文中,它返回一个空列表,默认情况下不会将其分配到任何位置。在您的示例中,输出未更改的$_
;
强制reverse
进入标量上下文会改变其行为并使其成为反向字符串,默认情况下使用$_
。因为say
可用于打印列表和标量,所以它不会强制其参数进入标量上下文。
Perl可能会执行DWIM,只是针对“I”的给定值。
在以下情况下反向的细分:
#!/usr/bin/env perl
use strict;
use v5.12;
my $inscalar = "foo bar";
# `reverse` is in list context, $in is coerced to a single-element list
my @outlist = reverse $inscalar;
# `reverse` is in scalar context, so it reverses strings
my $outscalar = reverse $inscalar;
say join(" | ", @outlist); # prints "foo bar"
say $outscalar; # prints "rab oof"
# the "normal" behaviour of `reverse`
my @inlist = qw(foo bar);
@outlist = reverse @inlist;
say join(" | ", @outlist); # prints "bar | foo"
答案 1 :(得分:3)
为什么我需要强制它明确地成为标量?
作为documented,reverse
在列表上下文中使用时反转参数列表元素的顺序。例如,reverse 'a', 'b', 'c'
会返回'c', 'b', 'a'
。
不能Perl DWIM?
是的,它可以做你想要的(没有参数表达式时的标量行为)。
但是,这可能令人困惑。我想不出任何其他运算符会根据缺少参数表达式来改变行为(而不是缺少参数)。