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

Hello monks, I am trying to set a value to a scalar inside an object directly, without using accessor and mutator methods. The objects code is:
package Lala; use strict; our $name = ""; sub newlala($) { my $self = {}; bless $self; return $self; } sub setname($) { my $self = shift; $name = shift; } sub getname() { return $name; } 1;
With this code i can simply write:
my $ref = Lala->newlala(); $ref->setname("Moufa"); my $name = $ref->getname(); print "Got name(ref): $name\n"; my $ref1 = Lala->newlala(); $ref1->setname("Troufa"); $name = $ref1->getname(); print "Got name(ref1): $name\n"; my $ref2 = Lala->newlala(); $ref2->$name="TRalala"; $name = $ref2->getname(); print "Got name(ref2): $name\n";
and works fine but what i cannot do (and i want to) is
my $ref2 = Lala->newlala(); $ref2->$name="TRalala";
Any ideas? Thanks!

Replies are listed 'Best First'.
Re: Acessing an object's variable
by Perl Mouse (Chaplain) on Dec 13, 2005 at 10:09 UTC
    $name is not a variable associated with an object. It's a package level variable - if you'd make several objects of the same class, they will all share the same name.

    To make object level variables, you need to use the reference (the object itself) in some way. Traditional is it to stuff the attribute (the object variable) inside the reference, but that's considered bad by some programmers (including myself).

    A technique would be to use inside-out objects:

    package LaLa; use strict; use warnings; use Scalar::Util 'refaddr'; my %name; sub newlala { # No point in using prototypes for methods. my $class = shift; return bless \do {my $var}, $class; # Always use two-arg bless } sub setname { my $self = shift; $name{refaddr $self} = shift; } sub getname { my $self = shift; return $name{refaddr $self} } sub DESTROY { my $self = shift; delete $name{refaddr $self} } 1;
    This prevents directly accessing the object variables - and that's considered a good thing.

    You could do that with tradional OO programming. No doubt someone else will show you the dark way.

    Perl --((8:>*
      This is very good! Thanks a lot for your reply. I just realized that each call to setname() reset the $name value causing it to keep only the last one. I didnt know about refaddr by the way. So the code you wrote ties values to a hash with the refaddr as the key. This is very nice but it is not what i would call object orientation really. I have been writing in java for the past few years so this looks to me more like hack than an OO solution. Is this the best way to do what i originally intended to? (i find it a bit hard to fully understand perlboot/toot) Again thanks very much
        Perl OO is a hack. As Larry has said, it was an exercise in minimalism - it proves that you can do OO with extremely little support from the language.

        That's why OO in perl6 will look quite different - it has solved the problem of needing hacks to have objects with data.

        I'm afraid that as long as you hava a Java mindset (nothing wrong with that), Perl OO will remain a major disappointment to you. And I can't disagree with you - I don't like Java, but I vastly prefer its OO system over Perls'.

        Perl --((8:>*
Re: Acessing an object's variable
by Anonymous Monk on Dec 13, 2005 at 12:32 UTC