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

时间:2012-07-12 01:19:22

标签: 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";} 

我没有输出。但是,如果我将$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()根本没有效果的顶级?

2 个答案:

答案 0 :(得分:12)

首先,您应该始终使用

开始Perl脚本
use strict;
use warnings;

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

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

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

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)。这有助于避免某些nasty problems

答案 1 :(得分:1)

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

#p>方式#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'};

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