jimbend has asked for the wisdom of the Perl Monks concerning the following question:

Good day -

I am creating two instances of package Cluster defined below. I thought that the output of the following would yield 'One One'....
$test1 = Cluster->new("One"); print $test1->getClusterName()." "; $test2 = Cluster->new("Two"); print $test1->getClusterName();
...but I'm getting..'One Two'. Can someone point out the error of my ways and how to correct this? Many thanks!
package Cluster; sub new { my $class = shift; my $self = {}; $self{_clusterName} = shift; $self{_verbs} = []; bless $self, $class; return $self; } sub getClusterName { my( $self ) = @_; return $self{_clusterName}; } 1;

Replies are listed 'Best First'.
Re: Losing a reference to a package instantiation
by ikegami (Patriarch) on Jan 01, 2010 at 23:23 UTC

    Use use strict; use warnings;!!

    You're modifying hash %self instead of modifying the hash referenced by $self.

Re: Losing a reference to a package instantiation
by Corion (Patriarch) on Jan 01, 2010 at 23:25 UTC

    If you used the strict pragma, Perl would tell you what you're doing wrong. You're using two different variables. One, lexical, variable, $self, and another, global, variable %Cluster::self, which you overwrite with the clustername every time you assign.

    You might want to take a look at tye's References Quick Reference.

Re: Losing a reference to a package instantiation
by biohisham (Priest) on Jan 01, 2010 at 23:46 UTC
    Welcome to The Monastery...

    You are dealing with %self keys where you actually needed to deal with the referenced anonymous hash $self in the constructor and the getClusterName() methods instead because that is what you intended by initializing an anonymous hash via "$self={}". Using strictures is note-worthy at discovering such mix-ups.
    #"Cluster.pm" use strict; use warnings; package Cluster; sub new { my $class = shift; #The first argument passed to the #new method is the name of the class my $self = {}; $self->{_clusterName} = shift; #Read data passed to constructor $self->{_verbs} = []; bless $self, $class; return $self; } sub getClusterName { my( $self ) = @_; return $self->{_clusterName}; } 1;
    use strict; use warnings; use Cluster; my $test1 = Cluster->new("One"); print $test1->getClusterName()." "; my $test2 = Cluster->new("Two"); print $test1->getClusterName()." "; print $test2->getClusterName();
    #OUTPUT: one One Two

    Have a happy Perl journey :)...


    Excellence is an Endeavor of Persistence. Chance Favors a Prepared Mind.