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";} 

出力がありません。ただし、中に入れる$obmy()

#!/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() );
}

return2行目で新しいオブジェクトが呼び出されていることに注意して->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モジュールは、2つの異なる方法で機能するように意図的に設計されています。

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

この3番目の方法は、モジュールが独自のオブジェクト内にツリーを格納するため、たまたま機能します。混乱を招き、モジュールの将来のバージョンで変更される可能性があるため、この方法での使用は避けることをお勧めします。

于 2013-04-26T18:33:42.963 に答える