我使用perl的XML::LibXML编写了一个程序
它使用 load_xml() 创建一个 XML::LibXML。
令我惊讶的是它不需要调用 new()。
什么时候需要调用new()?
这是(对我来说)令人惊讶的代码:
#!/usr/bin/env perl
use 5.020;
use warnings;
use XML::LibXML;
#the input xml
my $inputstr = <<XML;
<a>
<b class="type1">some type 1 data</b>
<b class="type2">some type 2 data</b>
<b class="type3">some type 3 data</b>
<b class="type4">some type 4 data</b>
<b notaclass="type1">don't change this</b>
<c class="type1">don't change this either</c>
</a>
XML
my $dom = XML::LibXML->load_xml(
string => $inputstr
);
say $dom->toString();
XML::LibXML
使用一种风格,其中方法既可以用作对象方法,也可以用作类方法。这是为了方便。如果您调用 XML::LibXML->load_xml
,它将为您创建一个解析器对象,使用您的参数对其进行配置,加载 XML,然后将解析器对象抛出。
sub load_xml {
my $class_or_self = shift;
my %args = map { ref($_) eq 'HASH' ? (%$_) : $_ } @_;
my $URI = delete($args{URI});
$URI = "$URI" if defined $URI; # stringify in case it is an URI object
my $parser;
# if called as an object method
if (ref($class_or_self)) {
$parser = $class_or_self->_clone();
$parser->{XML_LIBXML_PARSER_OPTIONS} = $parser->_parser_options(\%args);
# if called as a class method
} else {
$parser = $class_or_self->new(\%args);
}
这意味着这两段代码是等价的。
my $dom = XML::LibXML->load_xml(
string => $inputstr
);
my $dom = XML::LibXML->new(
string => $inputstr
)->load_xml(
string => $inputstr
);
什么时候需要调用 new()?
当您想要更改默认解析器选项并重用解析器对象时。或者当您想使用只能作为对象方法使用的方法时。
例如,您可能希望将配置好的 XML 解析器传递到另一个函数中,或者使用它来配置另一个对象的行为。
my $parser = XML::LibXML->new(pedantic_parser => 1);
my $object = Some::Class->new(xml_parser => $parser);
# This will use $parser which has been configured to be pedantic.
$object->do_something_with_an_xml_document($document);