2

我需要一些帮助来解码这个 perl 脚本。$dummy 没有在脚本中的其他任何地方初始化。脚本中的以下行是什么意思?为什么这意味着 split 函数没有任何参数?

($dummy, $class) = split;

该程序正在尝试使用某种统计分类方法来检查陈述是真还是假。因此,假设它计算并将以下数字赋予“真实性”和“虚假性”,然后检查测谎仪是否正确。

# some code, some code...
$_ = "truth"
# more some code, some code ...

$Truthsity = 9999
$Falsity = 2134123

if ($Truthsity > $Falsity) {   
    $newClass = "truth";      
} else {
    $newClass = "lie";     
}

($dummy, $class) = split;

if ($class eq $newClass) {
    print "correct";
} elsif ($class eq "true") {
    print "false neg";
} else {
    print "false pos"
}
4

3 回答 3

5
($dummy, $class) = split;

拆分返回一个值数组。第一个放入$dummy,第二个放入$class,任何其他值都将被忽略。第一个 arg 可能被命名为 dummy 因为作者计划忽略该值。更好的选择是使用 undef 忽略返回的条目:( undef, $class ) = split;

Perldoc 可以向您展示拆分功能的方式。当不带参数调用时, split 将对$_空格进行操作和拆分。 $_是 perl 中的默认变量,将其视为由上下文定义的隐含的“它”。

使用隐含的 $_ 可以使短代码更简洁,但在较大的块中使用它是一种糟糕的形式。您不希望读者对您要使用的“它”感到困惑。

split ;                      # split it
for (@list) { foo($_) }      # look at each element of list, foo it.
@new = map { $_ + 2 } @list ;# look at each element of list, 
                             # add 2 to it, put it in new list
while(<>){ foo($_)}          # grab each line of input, foo it.

perldoc -f split

如果省略 EXPR,则拆分 $_ 字符串。如果 PATTERN 也被省略,则在空白处拆分(在跳过任何前导空白之后)。任何与 PATTERN 匹配的内容都被视为分隔字段的分隔符。(请注意,分隔符可能超过一个字符。)

我非常喜欢使用三元运算符? :来设置字符串值并将逻辑推入块和子程序中。

my $Truthsity = 9999
my $Falsity   = 2134123

print test_truthsity( $Truthsity, $Falsity, $_ );

sub test_truthsity {
  my ($truthsity, $falsity, $line ) = @_;
  my $newClass = $truthsity > $falsity ? 'truth' : 'lie';
  my (undef, $class) = split /\s+/, $line ;

  my $output = $class eq $newClass ? 'correct' 
             : $class eq 'true'    ? 'false neg'
             :                       'false pos';
  return $output;
}

这个版本可能有一个微妙的错误。 split没有 args 与 不完全相同split(/\s+/, $_),如果行以空格开头,它们的行为会有所不同。在完全限定的拆分中,将返回空白的前导字段。 split没有 args 会删除前导空格。

$_ = "  ab cd";
my @a = split             # @a contains ( 'ab', 'cd' );
my @b = split /\s+/, $_;  # @b contains ( '', 'ab', 'cd')
于 2011-12-16T21:11:22.573 回答
3

从文档中split

拆分 /PATTERN/,EXPR

如果省略 EXPR,则拆分 $_ 字符串。如果 PATTERN 也被省略,则在空白处拆分(在跳过任何前导空白之后)。任何与 PATTERN 匹配的内容都被视为分隔字段的分隔符。(请注意,分隔符可能超过一个字符。)

因此,由于模式和表达式都被省略了,我们将默认变量拆分为$_空格。

变量的目的$dummy是捕获从 split 返回的列表的第一个元素并忽略它,因为代码只对第二个元素感兴趣,它被放入$class.

您必须查看周围的代码以找出$_上下文中的内容;它可能是循环变量或map块中的列表项,或其他东西。

于 2011-12-16T21:10:39.750 回答
2

如果您阅读文档,您会发现:

  • 第一个操作数的默认值为" ".
  • 第二个操作数的默认值为$_.
  • 第三个操作数的默认值为0.

所以

split

简称

split " ", $_, 0

这意味着:

取 $_,将其值拆分为空格,忽略前导和尾随空格。

第一个结果字段放在 中$dummy,第二个放在 中$class

根据它的名称,我认为您将不再使用$dummy它,因此它只是充当占位符。不过,你可以摆脱它。

my ($dummy, $class) = split;

可以写成

my (undef, $class) = split;   # Use undef as a placeholder

或者

my $class = ( split )[1];     # Use a list slice to get second item
于 2011-12-17T05:44:30.310 回答