Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Self creating OO Module field accessors...

by Perl Mouse (Chaplain)
on Jan 12, 2006 at 23:04 UTC ( #522838=note: print w/replies, xml ) Need Help??


in reply to Self creating OO Module field accessors...

There are a gazillion Class:: modules that will do that for you. What you also can do is:
for my $prop (qw [field1 field2 field3]) { eval sprintf <<'END', ($prop) x 3; sub %s { my $self = shift; if (@_) {$self->{%s} = shift}; return $self->{%s}; } } END }
Then you won't have any runtime penalty due to AUTOLOAD, or whatever runtime solution your Class:: choice uses.

Or you could use a smart editor that allows you to create an accessor using a macro.

Personally, if I find myself making enough accessors in a class that I start contemplating automating it, I wonder whether I really need an object, or whether I'm just creating a glorified struct. It's usually the latter - and Perl already has an excellent data structure to use as a struct: it's called a hash.

Perl --((8:>*

Replies are listed 'Best First'.
Re^2: Self creating OO Module field accessors...
by hv (Parson) on Jan 13, 2006 at 11:41 UTC

    What you also can do is:

    for my $prop (qw [field1 field2 field3]) { eval sprintf <<'END', ($prop) x 3; sub %s { my $self = shift; if (@_) {$self->{%s} = shift}; return $self->{%s}; } } END }

    I used to generate accessors in this way, in part because I felt that glob manipulation was scary and turning off strictness, however temporarily, was fragile. Tom Christiansen eventually managed to convince me that the eval approach is bad - firstly it is wasteful of memory (and processor) because each method is recompiled afresh; secondly because it is deferred, and so a perl -c check won't show problems.

    So these days I do it more like this:

    for my $method (qw/ field1 field2 field3 /) { no strict 'refs'; *$method = sub { use strict 'refs'; my $self = shift; if (@_) {$self->{$method} = shift}; return $self->{$method}; }; }

    Rather than creating 3 independent blocks of code, this creates 3 closures over the same block of code; in practice the resulting methods are otherwise identical. I also feel they are much easier to read this way, which is another aid for debugging and maintenance.

    (I saw an alternative approach to the strictness here recently:

    for my $method (qw/ ... /) { my $sub = sub { the code ... }; no strict 'refs'; *$method = $sub; }
    .. which is probably better, but I haven't started using it yet.)

    See Re: Things I Don't Use in Perl for some other things my autogenerated methods do.

    Hugo

      IMO There is a big advantage to the first style however: it actually defines the subs in such a way that you don't get weird error messages about stuff happening in an anon sub. Likewise you can set breakpoints in the debugger and stuff with the former but with the latter its not so easy. There are ways around this, but they aren't straight-forward.

      use Carp qw(confess); local *foo=sub { confess "What the fook!" }; eval qq[sub bar { confess "What the wook!" } 1 ] or die "failed to eval code: $@"; eval { foo(); 1 } or print $@; eval { bar(); 1 } or print $@; __END__ What the fook! at c:\temp\die.pl line 3 main::__ANON__() called at c:\temp\die.pl line 9 eval {...} called at c:\temp\die.pl line 8 What the wook! at (eval 1) line 1 main::bar() called at c:\temp\die.pl line 13 eval {...} called at c:\temp\die.pl line 12
      ---
      $world=~s/war/peace/g

Re^2: Self creating OO Module field accessors...
by blue_cowdawg (Monsignor) on Jan 12, 2006 at 23:10 UTC
        Personally, if I find myself making enough accessors in a class that I start contemplating automating it, I wonder whether I really need an object, or whether I'm just creating a glorified struct.

    I hear you! If all this module was functionally only a struct I'd certainly agree with you. Except in the case of this module there is a lot more going on.

    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
      You might consider whether you have an object that has-a struct that you should allow public access to. Then you'd need only one accessor method that returns a ref to the struct and allow the user to stomp all over it access its fields as required. :-)

      Caution: Contents may have been coded under pressure.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://522838]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (2)
As of 2020-10-24 18:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My favourite web site is:












    Results (246 votes). Check out past polls.

    Notices?