使用my()可以彻底改变XML :: Bare行为

bar*_*ter 2 xml perl

当我运行这个Perl脚本时:

#!/bin/perl 
use XML::Bare; 
$ob = new XML::Bare(text=>'<xml><name>Bob</name></xml>'); 
for $i (keys %{$ob->{xml}}) {print "KEY: $i\n";} 
Run Code Online (Sandbox Code Playgroud)

我没有输出.但是,如果我放入$ob一个my():

#!/bin/perl 
use XML::Bare; 
my($ob) = new XML::Bare(text=>'<xml><name>Bob</name></xml>'); 
for $i (keys %{$ob->{xml}}) {print "KEY: $i\n";} 
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

KEY: _z 
KEY: _i 
KEY: xml 
KEY: _pos 
Run Code Online (Sandbox Code Playgroud)

为什么会my()如此彻底地改变这种行为,特别是考虑到我处于最高级别my()应该没有任何影响?

fri*_*edo 12

首先,您应该始终使用Perl脚本

use strict;
use warnings;
Run Code Online (Sandbox Code Playgroud)

这将迫使您声明所有变量,my以捕获许多拼写错误和简单错误.

在您的情况下,实际上并不是my导致更改的行为,而是括号,它放在$ob列表上下文中.

看一下XML :: Bare 的源代码,我们在构造函数中找到了这个:

sub new { 
    ...
    bless $self, $class;
    return $self if ( !wantarray );
    return ( $self, $self->parse() );
}
Run Code Online (Sandbox Code Playgroud)

请注意,第二return行为您调用->parse了新对象,您在第一个示例中忘记了这一点,这就是为什么那个没有任何数据的原因.

所以你可以说

my $obj = XML::Bare->new(text=>'<xml><name>Bob</name></xml>'); # in scalar context
$obj->parse;
Run Code Online (Sandbox Code Playgroud)

要么

my ( $obj ) = XML::Bare->new(text=>'<xml><name>Bob</name></xml>'); # in list context
Run Code Online (Sandbox Code Playgroud)

它们应该是等价的.

这是一个非常奇怪的界面选择,但我不熟悉XML::Bare.

另请注意,我避免使用间接方法语法(XML::Bare->new而不是new XML::Bare).这有助于避免一些令人讨厌的问题.

  • `my($ foo)`相当于`(my $ foo)`,而`(...)=`告诉Perl使用列表赋值运算符而不是标量赋值运算符.请参阅[迷你教程:标量与列表分配运算符](http://www.perlmonks.org/?node_id=790129) (2认同)