use strict;
use warnings;
use Test::More;
subtest 'explicit array' => sub {
my @row = (1,2,3);
# let's disassamble the array.
# without default it works:
my ($one, $two, $three) = @row;
is($one, 1, 'one');
# this works too:
($one, $two, $three) = @row ? @row : (10,20,30);
is($one, 1, 'one');
# and the default hits
my @emptyness;
($one, $two, $three) = @emptyness ? @emptyness : (10,20,30);
is($one, 10, 'one default');
# however, this squashes the array to a scalar
($one, $two, $three) = @row // (10,20,30);
is($one, 3, 'scalar, length');
is($two, undef, 'nothing else');
# shouldn't 'defined-or' be equivalent to a ternary with a check against undef?
# ($one, $two, $three) = defined @emptyness ? @emptyness : (10,20,30); # fails!
# "Can't use 'defined(@array)' (Maybe you should just omit the defined()?)"
# Probably @array // ... should fail in the same way, but instead it returns @array
# in a scalar context.
# so maybe this is a bug
};
done_testing();
Run Code Online (Sandbox Code Playgroud)
或者有人可以给我这种行为的合理解释吗?
您所观察到的行为是预期的行为。这记录在perlop 的Logical Defined-Or部分中:
EXPR1 // EXPR2
如果定义则返回 的值,否则返回EXPR1
的值。EXPR2
(在标量上下文中,在 // 本身的上下文中EXPR1
计算)。EXPR2
并且,perldoc 后来提供了以下示例:
特别是,这意味着您不应该使用它来在两个聚合之间进行选择以进行分配:
Run Code Online (Sandbox Code Playgroud)@a = @b || @c; # This doesn't do the right thing @a = scalar(@b) || @c; # because it really means this. @a = @b ? @b : @c; # This works fine, though.
归档时间: |
|
查看次数: |
158 次 |
最近记录: |