in reply to Re^3: Modules for autogenerating accessor/mutator methods
in thread Modules for autogenerating accessor/mutator methods

I hear you; I have not found an accessor-generating module that was worth the trouble. But to be fair, I haven't looked too hard since I don't do much module writing (most of my coding is scripts), so my needs in this regard are very modest. For the few modules I write (which are usually relatively simple) I get by with AUTOLOAD, which I still consider lazier than typing out a dozen accessors, even if the "typing" amounts to as little as a brief exercise in cutting and pasting.

the lowliest monk

  • Comment on Re^4: Modules for autogenerating accessor/mutator methods

Replies are listed 'Best First'.
Re^5: Modules for autogenerating accessor/mutator methods
by tilly (Archbishop) on Jun 05, 2005 at 00:05 UTC
    You're using a sledgehammer to swat fleas.

    Typeglob a bunch of closures. Save AUTOLOAD for a problem that needs the power. Here is an untested version.

    package Whatever::Makes::Sense; sub create_accessors { my $class = caller(); foreach my $accessor (@_) { no strict 'refs'; *{"$class\::$accessor"} = sub { my $self = shift; $self->{$accessor} = shift if @_; return $self->{$accessor}; }; } } # And elsewhere... Whatever::Makes::Sense::create_accessors(qw(foo bar baz));
    Drawbacks? You have to write the line of code that lists the accessors. Advantages? You leave AUTOLOAD free to do something else, you don't get things that you didn't intend to AUTOLOAD being AUTOLOADed, your methods are visible to UNIVERSAL::can, missing methods don't get accidentally interpreted as accessors (a good AUTOLOAD can address this, but requires more code)...

      As I already made clear, I use AUTOLOAD for very simple modules. In fact, I have never needed AUTOLOAD for anything else, so I have not attained the point of wanting to "save it". (What can I say? I'm a lowly script writer, not a heavy-hitting module meister.) I'm aware of the technique you describe, though I am sorry to say that I use it with AUTOLOAD:

      sub AUTOLOAD { my $self = $_[ 0 ]; ( my $name = our $AUTOLOAD ) =~ s/.*:://; return if $name eq 'DESTROTY'; die "Unknown field: $name" unless exists $self->{ $name }; no strict 'refs'; *$AUTOLOAD = sub { my $self = shift; return @_ ? $self->{ $name } = shift : $self->{ $name + }; }; goto &$AUTOLOAD; }
      (Yes, I posted a different version in another the reply, because I think it is more standard and easier to follow.)

      So, please tell me, what are the things one should be saving AUTOLOAD for instead of wasting it on accessors?

      Update: Bug in the original version fixed.

      the lowliest monk

        Off the top of my head, delegation.
      At least I understand perfectly this one, while the AUTOLOAD stuff remains black magic to me :) Thank you so much, tilly!
        You're welcome. Your response illustrates yet another advantage of this technique - it is easier to figure out what is going on when you see it.
Re^5: Modules for autogenerating accessor/mutator methods
by wazoox (Prior) on Jun 04, 2005 at 22:43 UTC
    Could you please explain a bit the AUTOLOAD magic? I don't get it :)

      It goes something like this:

      sub AUTOLOAD { my $self = $_[ 0 ]; ( my $name = our $AUTOLOAD ) =~ s/.*:://; return if $name eq 'DESTROTY'; die "Unknown field: $name" unless exists $OK_FIELDS{ $name }; return @_ ? $self->{ $name } = shift : $self->{ $name }; }
      As you can infer from the above, this version assumes that the instances of this class are implemented as hash refs. However, I don't like using AUTOLOAD when I have a lot of inheritance going on (but then, I don't use inheritance much).

      I've seen many descriptions of this technique. You can find one in this section of perltoot. Also, The Perl Cookbook, the Alpaca book, Object Oriented Perl discuss the use of AUTOLOAD to generate accessors. I'm sure this list is far from exhaustive.

      the lowliest monk

        Thanks, I'll look into the docs. However I'm too young in OOP to try anything like this at the moment :)

      You setup a constant or package variable or what not that has a list of what your member names are. You then write a sub AUTOLOAD { ... } which looks to see if $AUTOLOAD is in that list and if so maps it into retrieving (or setting if given argument(s)) $self->{"_$AUTOLOAD"} as appropriate (possibly generating a coderef which does the same thing and assigning that to the correct glob so AUTOLOAD is bypassed the next time).

      --
      We're looking for people in ATL