Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

how to make a package variable as c++

by anaconda_wly (Scribe)
on Nov 04, 2012 at 09:12 UTC ( #1002176=perlquestion: print w/ replies, xml ) Need Help??
anaconda_wly has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monks: I used to use c++, but beginner for perl. I want to create a singleten class with a bunch of attributes and methods but didn't know how.

use strict; use warnings; package MyConfig; use XML::Simple; my $singleton; my $XMLfile_name=""; my @hostList = (); sub new { my $class = shift; #create singleton $singleton ||= bless {}, $class; #Error here: Useless use of hash element in void context $singleton->{$XMLfile_name}=$_[0]; return $singleton; } sub loadConfig{ my $self=shift; my $xml = XML::Simple->new; my $config = $xml->XMLin($file_name, ForceArray => [ 'host', 'component' ]) or die$!; my $index=0; while($config->{host}->{component}->[$index++]) { push @hostList, $config->{host}->{component}->[0]->{component_name}; } } 1;

The XML structure is like:

<root> <component component_name="n1" /> <component component_name="n2" /> <component component_name="n3" /> </root>

I call code as:

use strict; use MyConfig; my $CONFIG = "somefile.xml"; &main; sub main { my configReader = MyConfig->new( $CONFIG ); configReader->loadConfig; }

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.

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 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!!

Comment on how to make a package variable as c++
Select or Download Code
Re: how to make a package variable as c++
by aitap (Deacon) on Nov 04, 2012 at 09:37 UTC

    #Error here: Useless use of hash element in void context $singleton->{$XMLfile_name}=>$_;
    something => another_thing means "something", another_thing (note the quotes, see Comma Operator for more info). Did you mean just "="?

    You also seem to use $_ instead of elements in @_. Fuction arguments are in the @_ array (which is modified by shift, by the way), not in the single $_ scalar variable.

    Sorry if my advice was wrong.
      Yes, the error due to a typo. Thanks!
      Thanks Aitap, I alway forget that by using $_ instaed of $_[0]. But seems I can't fix/update the post after replied.
      I didn't noticed I'm logged out. I have changed the error. But could you or anyone else please give me any directions of my questions?
Re: how to make a package variable as c++
by tobyink (Abbot) on Nov 04, 2012 at 10:33 UTC

    "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'
      OK. Firstly thank you tobyink. I understand you answer to my 2nd question. I asked this because I think $self is something like this pointer in c++. So as you indicate, I see in perl, class itself can be an invoker when as a class method, in the method, sometimes the first input what's commonly named $self is a class, sometimes is an object, no difference when using inside the method.
      I'm studying you code and reading perl docs in the meantime. It may take some time to degest your code. And thanks more.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1002176]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (6)
As of 2014-08-30 10:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (292 votes), past polls