2

当我运行这个 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";} 

我没有输出。但是,如果我放入$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";} 

我得到这个输出:

KEY: _z 
KEY: _i 
KEY: xml 
KEY: _pos 

为什么要my()如此彻底地改变这种行为,特别是考虑到我处于顶层,my()根本不应该有任何影响?

4

2 回答 2

11

首先,您应该始终以您的 Perl 脚本开头

use strict;
use warnings;

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

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

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

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

请注意,第二return行为您调用->parse了新对象,而您在第一个示例中忘记了这样做,这就是该对象中没有任何数据的原因。

所以你可以说

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

或者

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

他们应该是等价的。

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

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

于 2012-07-12T01:35:12.403 回答
1

XML::Bare 模块被有意设计为以两种不同的方式工作。

方式#1:

my $ob = XML::Bare->new( text => "<xml/>" );
my $tree = $ob->parse();

方式#2:

my ( $ob, $tree ) = XML::Bare->new( text => "<xml/>" );

您正在以未记录的方式使用该模块#3:

my ( $ob ) = XML::Bare->new( text => "<xml/>" );
my $tree = $ob->{'xml'};

第三种方式恰好可行,因为模块将树存储在它自己的对象中。我建议避免以这种方式使用它,因为它会令人困惑,并且可能会在模块的未来版本中发生变化。

于 2013-04-26T18:33:42.963 回答