in reply to
how to make a package variable as c++
"As you see, I didn't know how to create and use what we say member variable in c++. The $XMLfile_name and the @hostList here is using as member variables. @hostList used for holding results parsed from the XML file."
As per $singleton = bless {}, $class, the singleton object is a blessed hash, right? Hmm... now I wonder how you can associate a couple bits of data with the object?
$singleton->{xml_filename} = $_[0];
$singleton->{hostlist} = \@hostlist;
"Another question: In the new method, as I read package method always put the invoker as the first argument. I suppose 'invoker' for new() means the class MyConfig and return an instance after blessed; And the 'invoker' for loadConfig seems change to be an instance, seems the $self by te first default argument is an instance not the class any more. But as I know the 'new' is an ordinary method as others, not a keywords, why they behaves different?"
The invocant is whatever is on the left side of the arrow operator ->. So:
Dancer->new; # invocant is "Dancer"
$obj->dance; # invocant is $obj
"The last question:I don't think I made my while condition correct. How can I deal with the while index simply using $_? Thanks a lot in advance!!"
You could use a foreach loop, a la:
my @components = @{ $config->{host}->{component} };
foreach (@components)
{
push @hostList, $_->{component_name};
}
Though personally I'd just use map; no explicit looping construct necessary:
push @hostList,
map { $_->{component_name} }
@{ $config->{host}->{component} };
That said, I'd recommend looking at Moose and MooseX::Singleton. Moose takes away a lot of the boilerplate OO "plumbing" necessary in Perl, allowing you to concentrate on the interesting stuff.
{
package MyConfig;
use Moose;
use MooseX::Singleton;
use XML::Simple;
has xml_filename => (
is => 'ro',
isa => 'Str',
required => 1,
);
has _config => (
is => 'ro',
isa => 'Any',
lazy_build => 1,
);
has hostlist => (
is => 'ro',
isa => 'ArrayRef',
lazy_build => 1,
);
sub _build__config {
my $self = shift;
my $xml = XML::Simple->new;
$xml->XMLin($self->xml_filename, ForceArray => [ 'host', 'comp
+onent' ])
or die $!;
}
sub _build_hostlist {
my $self = shift;
my @hostlist =
map { $_->{component_name} }
@{ $self->_config->{host}[0]{component} };
return \@hostlist;
}
}
my $config = MyConfig->new(xml_filename => "myconfig.xml");
my @hostlist = @{ $config->hostlist };
print "@hostlist";
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'