Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Objects as arrays but with autogenerated getters + setters

by tinita (Parson)
on Jun 26, 2006 at 20:51 UTC ( #557659=perlquestion: print w/replies, xml ) Need Help??

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

hi monks,

I'm a big fan of objects that are implemented as arrays.
They save a bit cpu, they save a bit memory, and while it may not be much, the fact that it's saving cpu *and* memory attracts me =)

also, with arrays instead of hashes, I can't be tempted to access the attributes by accessing the hash directly.

I can't find a module on CPAN that does that for me. Class::Accessor and similar modules use hashes.
Is there a module that does that? Otherwise I would like to write a little module myself (I know, there are already a lot of these kind of modules...). Here's a starter:

package Class::Accessor::Eval; use Carp qw(croak carp); use strict; use warnings; sub import { my ($self, %args) = @_; my $get = $args{get}; my $set = $args{set}; my $names = $args{names}; my $class = caller(); for my $i (0..$#$names) { my $name = $names->[$i]; my $get = $get; my $set = $set; for ($get, $set) { s/\$name/$name/g; s/\$i/$i/g; } my $code = <<"EOM"; package $class; $get $set EOM eval $code; if ($@) { croak "Error compiling $name: $@\n"; } } } 1; ############# package Foo; use Class::Accessor::Eval get => <<'EOM', sub get_$name { $_[0]->[$i] } EOM set => <<'EOM', sub set_$name { $_[0]->[$i] = $_[1] } EOM names => [qw(name age city job salary ...)]; ##################### package main; my $foo = bless ["foo", 100], "Foo"; use Data::Dumper; warn Data::Dumper->Dump([\$foo], ['foo']); print $foo->get_age,$/; $foo->set_age(23); print $foo->get_age,$/;
a 'new' method is missing, and a default if you don't want to write the get/set yourself.

any comments? If noone finds that a useful module it's probably worthless to upload it. I'm also seeking for a better name.

update: maybe Class::Accessor::Fast::Array would be a possibility. that would keep it simple and follow the standard of Class::Accessor

update2: marty (Class::Accessor) actually will release an additional module that would work like my C::A::F::Array idea. he has the code ready, it just needs to be tested and released.

Replies are listed 'Best First'.
Re: Objects as arrays but with autogenerated getters + setters
by Solo (Deacon) on Jun 26, 2006 at 21:02 UTC
    You might want to look at Class::MakeMethods.


    You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.
      thanks, I'll have a look at it. after a quick glance, I didn't find out how to use get_attr and set_attr method names, though.

        package Foo; use Class::MakeMethods::Template::Array ( 'new' => 'new', 'scalar' => [ -interface=> { 'get_*'=>'get', 'set_*'=>'set' }, qw/ name age city job salary /, ], ); package main; use Data::Dumper; my $foo = Foo->new(); $foo->set_name("foo"); $foo->set_age(100); warn Data::Dumper->Dump([$foo], ['foo']); print $foo->get_age,$/; $foo->set_age(23); print $foo->get_age,$/;


        You said you wanted to be around when I made a mistake; well, this could be it, sweetheart.
Re: Objects as arrays but with autogenerated getters + setters
by HuckinFappy (Pilgrim) on Jun 26, 2006 at 21:35 UTC
      thanks, i will have a look at that, too. i thought in inside out objects attributes are stored in hashes with the object (stringified) as a key. that would be an extra hash lookup.

      edit: ah, a sequence number can be used for the id of an object. seems this could be what i want (edit2: although O::IO does way more than i need, and actually in some cases i might not want to use inside-out objects.)

Re: Objects as arrays but with autogenerated getters + setters
by ForgotPasswordAgain (Priest) on Jun 27, 2006 at 11:26 UTC
    I was wondering, since you want to save memory and CPU, whether you benchmarked your approach versus a simple hash-based approach (or others).
      yes, i did a simple benchmark:
      timethese($ARGV[0]||-1, { hash => sub { $foo->set_name("x");return $foo->get_name }, array => sub { $bar->set_name("x");return $bar->get_name }, });

      $foo is a blessed hash and $bar a blessed array. both have 15 attributes. the array subroutine takes about 93% of the time.

      memory saving depends, of course, on the length of the hash keys. with 15 hash keys of length 5 i save about 15% 35%. (measured with Devel::Size::total_size)

      edit: i measured wrong for the memory test. i was just copying references before.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://557659]
Approved by GrandFather
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (2)
As of 2023-09-25 00:36 GMT
Find Nodes?
    Voting Booth?

    No recent polls found