当我运行这个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()
根本没有效果的顶级?
答案 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'};
第三种方式恰好起作用,因为模块将树存储在它自己的对象中。我建议避免以这种方式使用它,因为它令人困惑,并且可能在模块的未来版本中发生变化。