Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Autoload versus auto-generating accessors

by goldenblue (Acolyte)
on Feb 11, 2016 at 15:54 UTC ( [id://1154972]=perlmeditation: print w/replies, xml ) Need Help??

after reading through PerlMonks Sections I decided this post should go here...

I have been using Autoload extensively for my getters and setters, and refrained from "auto-writing" them, basically because I didn't like how it looked in the code.

I also stumbled across some code that uses a baseclass with a makeattr-method it uses as "initializer", to write these accessors, which I also find pretty cool...

Now I was wondering, which method do others prefer?

So I would like to open a discussion:

    what are the advantages and drawbacks of each method, or do you see a third alternative? And which do you prefer?

Maybe someone with a higher level would like to make this into a poll?


--

Replies are listed 'Best First'.
Re: Autoload versus auto-generating accessors
by choroba (Cardinal) on Feb 11, 2016 at 15:58 UTC
    Technical: You don't need to be a higher level to create a poll. See How do I create a Poll?.

    For very simple stuff, I usually use Object::Tiny, but I've heard Class::Tiny is better. For more advanced stuff, I turn to Moo. For the most complex stuff, people use Moose.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      Technical: You don't need to be a higher level to create a poll. See How do I create a Poll?

      right... read through that after posting... duh!

      I work on systems where I have little pre-assumptions on which modules are available. So I can't realy on modules from cpan.

      As of now, I am even restricted to using perl 5.8.8.0. There might be an upgrade in the future and I'd suggest including such modules, but alas... that will be a complicated procedure.

      Therefore, when I start with a new framework, I rely onto very basic methods... therefore my question.

      Well, if everyone relies onto cpan modules, this discussion seems of little use... but maybe there are folks out there (in here, actually) that do still implement stuff 'from scratch'?


      --
Re: Autoload versus auto-generating accessors
by 1nickt (Canon) on Feb 11, 2016 at 16:59 UTC
    <$0.02>

    When I'm doing something so simple that Moo is more than I need, I usually turn to Class::Accessor::Fast. You could easily copy the source from Class::Accessor and/or Class::Accessor::Fast if you really can't install modules from CPAN.
    package Foo; use strict; use warnings; use parent 'Class::Accessor::Fast'; BEGIN { __PACKAGE__->mk_accessors(qw/ bar qux /); } sub new { my $class = shift; return $class->SUPER::new(); } 1; # return true
    perl -MFoo -E' my $foo = Foo->new; $foo->bar("baz"); $foo->qux( $foo->bar ); say $foo->bar; say $foo->qux; '
    Output:
    baz baz
    </$0.02>

    The way forward always starts with a minimal test.
Re: Autoload versus auto-generating accessors
by Arunbear (Prior) on Feb 12, 2016 at 10:58 UTC

    Compared to auto-generating, using Autoload is

    • Slower, because the inheritance hierarchy will be searched before getting to AUTOLOAD
    • Trickier - did you remember to handle DESTROY? Did you handle disallowed methods?

    But a more important question to consider is - Should I be using getters and setters?

    The short answer is "most likely not", but for more depth see BrowserUk's answer:Re: OOP's setter/getter method - is there a way to avoid them?

    Another good read is Why getter and setter methods are evil. Some relevant quotes are:
    A fundamental precept of OO systems is that an object should not expose any of its implementation details. This way, you can change the implementation without changing the code that uses the object. It follows then that in OO systems you should avoid getter and setter functions since they mostly provide access to implementation details.
    and
    This implementation hiding principle leads to a good acid test of an OO system's quality: Can you make massive changes to a class definition—even throw out the whole thing and replace it with a completely different implementation—without impacting any of the code that uses that class's objects? This sort of modularization is the central premise of object orientation and makes maintenance much easier. Without implementation hiding, there's little point in using other OO features.

      well... I do have @rw and @ro vars in the code that the Autoload checks against... And I don't protect against truly malicious code, it's all company internal. I basically wrote a Base class and want people to use it without too much effort... and handle all the 'if this is a reference to a hash, do this, if it a reference to an array...' so, the accessors are just supposed to be syntactic sugar. I don't like all the {''} extras...

      So, it is basically my way of using the 'public' interface of the class... What it does allow me is that when someone uses these accessors, I don't give away references to the data, but make sure that only copies are passed.

      If thatsyntactic sugar is used.

      also, I admit I am not concerned about speed.


      --

        I forget: my main reason for using OO-like implementation in perl is inheritance...

        And because all of the classes in this package are written that way...


        --
Re: Autoload versus auto-generating accessors
by VinsWorldcom (Prior) on Feb 11, 2016 at 16:28 UTC

    I barely tread water at this point as it hits the limits of my understanding of the object oriented model, but I'll offer this:

    • When I subclass a module, add some capability but then want all the parent's accessors available, I use AUTOLOAD. See Net::Telnet::Cisco source for an example - note it's not my module, but I've used that example in some of my stuff.

    • When I create my own stuff and the object has a ton of stuff that all needs accessors and they all are pretty much the same save for the key/value pair, I create them programmaticly. See Cisco::SNMP source for example, specifically the _mk_accessors_*() subs and how they're called from the sub modules (Cisco::SNMP::*)

      In what case don't you get the parent's accessors, anyway? Isnt that what subclassing is all about? What am I misunderstanding?


      --
Re: Autoload versus auto-generating accessors
by Anonymous Monk on Feb 11, 2016 at 16:36 UTC

    For simple variable access, I have been using something like ...

    package ... ; BEGIN { for my $opt ( qw< l i s t > ) { # Normalize. my $sub = lc $opt; $sub =~ tr/-/_/; no strict 'refs'; *$sub = sub { # get|set a variable based on number # (and/or kind, value) of arguments passed. }; } }

    ... Moo|Moose may allow less text to type; provide more flexibility, validation, etc; haven't bothered yet.

    As for not being able install new modules, you could copy the text of the modules which are written in pure Perl (don't need a C compiler). That won't help when the newer perl syntax is present, obviously.

Re: Autoload versus auto-generating accessors
by kbrannen (Beadle) on Feb 29, 2016 at 17:30 UTC
    I almost never use AUTOLOAD for performance reasons and to avoid the issue of it going to the wrong parent (if using inheritance). No, I've never had it go to the wrong parent, I'm just concerned about that. :)

    If the number of "getters" is 5 (or so) or less, I just hand code them. If it's a larger number, then I do something like the AM does above with:
    BEGIN { for my $opt ( qw< a b c d e f g > ) { no strict 'refs'; my $sub = "get_$opt"; *$sub = sub { $self=shift; return $self->{$opt}; }; } }
    I might have to have a hash or something that maps english names to internal names to help that out, but still, that's the basics of it and I've been pleased with it.

    I always hand code "setters" because there are normally so few of them, but I could do the above method for them too if I had to.

    HTH,
    Kevin

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://1154972]
Approved by Corion
Front-paged by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (6)
As of 2024-03-19 10:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found