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

I'm trying to use Class::Std, as described in "Perl Best Practices". The following code works just fine:
my $guy = Person->new({name => 'Bubba'}); print "name: ", $guy->get_name, "\n"; $guy->set_name('Gump'); print "name: ", $guy->get_name, "\n"; package Person; use Class::Std; { my %name_of :ATTR; sub BUILD { my ($self, $ident, $arg_ref) = @_; $name_of{$ident} = $arg_ref->{name}; return; } sub get_name { my $self = shift; return $name_of{ident $self}; } sub set_name { my ($self, $new_name) = @_; $name_of{ident $self} = $new_name; return; } }
But what I REALLY want to do is this:
my $guy = Person->new({name => 'Bubba'}); print "name: ", $guy->get_name, "\n"; $guy->set_name('Gump'); print "name: ", $guy->get_name, "\n"; package Person; use Class::Std; { my %name_of : ATTR(init_arg => 'name', get => 'name', set => 'name' +); }
But when I try I get the error message:
Can't locate object method "get_name" via package "Person" at ./oop.pl + line 4
I've also tried the perl6 syntax:
:init_arg<name> :get<name> :set<name>
but I get the same error.

Obviously, I'm missing something really important here... can anyone please help me out?

Thanks!

Replies are listed 'Best First'.
Re: Need help using Class:Std (with :ATTR)
by chromatic (Archbishop) on Feb 21, 2007 at 22:41 UTC

    Try reordering. This won't be a problem if you put Person in its own module, as you might do when creating a larger program:

    { package Person; use Class::Std; my %name_of : ATTR(init_arg => 'name', get => 'name', set => 'nam +e'); } package main; my $guy = Person->new({name => 'Bubba'}); print "name: ", $guy->get_name, "\n"; $guy->set_name('Gump'); print "name: ", $guy->get_name, "\n";

    (My reformattings make no difference; I just prefer them for clarity and separation.)

Re: Need help using Class:Std (with :ATTR)
by xdg (Monsignor) on Feb 22, 2007 at 15:07 UTC

    If you want to explore inside-out objects, I strongly recommend avoiding Class::Std and using the powerful Object::InsideOut or the simpler Class::InsideOut instead.

    Here's your example in O::IO

    package Person; { use Object::InsideOut; my @name_of :Field :Std_All(name); }

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.