racer_x has asked for the wisdom of the Perl Monks concerning the following question:
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: is autoload bad style?
by blokhead (Monsignor) on Jul 26, 2003 at 02:09 UTC | |
For instance, you could use AUTOLOAD to be lazy about providing object accessors. But I prefer this more explicit way: I got that idea from this post a while back. In my opinion, it's just a better way of "lazily" providing accessors than with AUTOLOAD. Although it's a little more typing, it's still much less typing that writing out every sub by hand, and it better expresses my intent. (i.e, I don't want to waste time filtering out every misspelled method call) Sometimes this isn't feasible -- sometimes it doesn't make sense to try anticipating every possibility. Other times you must cover different sets of method names depending on various contexts (i.e., you must look at the passed data and $AUTOLOAD before you know if it's a valid request). For instance, a while back I wrote a bare-bones object-persistence class à la Class::DBI. Because it was a superclass for many other object classes, I had to use AUTOLOAD for the accessors/mutators, because a name method might be ok for one subclass, but not another. This is where the power of AUTOLOAD really shines. blokhead | [reply] [d/l] |
|
Re: is autoload bad style?
by sauoq (Abbot) on Jul 26, 2003 at 02:11 UTC | |
so perhaps the answer is "It depends on how you use it"? Yep. That's the answer. It also depends on your requirements. That said, it is "standard fare". It's well supported and documented. So, to answer the question in the title, I'd say "no" with the caveat that it, like many of Perl's features, can certainly be abused. To see a standard and very good use for AUTOLOAD, perldoc AutoLoader. That's what it was developed for, I believe. It's very handy for modules like POSIX with lots and lots of functions, most of which may never be used by any one script. -sauoq "My two cents aren't worth a dime."; | [reply] |
|
Re: is autoload bad style?
by chromatic (Archbishop) on Jul 26, 2003 at 02:18 UTC | |
It depends on how you use it. I just whacked a nasty AUTOLOAD out of Everything a couple of days ago, but I use it often in other code where it belongs. | [reply] [d/l] |
by racer_x (Sexton) on Jul 26, 2003 at 06:06 UTC | |
| [reply] |
by chromatic (Archbishop) on Jul 26, 2003 at 06:49 UTC | |
In that case, yes, it was a mistake. It was a deliberate design decision. I understand the reason for using it. It's also going away unlamentedly. :) If it helps, both Python and Ruby have similar features. You can use it for anything from error checking to run-time function creation. Take a look at Test::MockObject for a better, or, at least, more interesting use of AUTOLOAD. | [reply] [d/l] |
|
Re: is autoload bad style?
by strat (Canon) on Jul 26, 2003 at 11:12 UTC | |
Somewhere at the beginning of the script I initialized a list which contained the attributes that are allowed for auto-generation. In AUTOLOAD, I check if the wanted method is allowed, and if yes, i create the interface method and goto that interface. I wouldn't like to do something without autoload ;-)
Best regards, | [reply] |
by ihb (Deacon) on Jul 26, 2003 at 18:41 UTC | |
What stopped you from generating the methods when loading the module? I can see why you'd perhaps want to delay creation of the methods if there are several hundreds of attributes and you might not use to many of them for each compilation. But you said you chose AUTOLOAD due to flexibility. What flexibility does AUTOLOAD give you that's not easily done without AUTOLOAD? It makes think you have indeterministic attribute names, or attribute names that are best expressed through a pattern. But you also say that you have a list with the attributes that are allowed for autogeneration. So it doesn't sound like it's that either. In either case I'd prefer to have generic &set_value and &get_value methods instead, where the first argument is the attribute name. This would also allow you to easier give better diagnostics, and if there is a couple of hundred attributes I'd expect a typo or two every now and then. Furthermore, if I needed to initialize more than a handful attributes I'd prefer, if possible, doing something like
over
or being forced to do some dynamic method lookup, e.g.
I really don't see the advantage of having an AUTOLOAD here. I just see disadvantages. Look at Re: is autoload bad style? for an explanation for my skepticism. If you do want to pre-generate the methods there are modules for that on CPAN to make it even simpler for you. ihb | [reply] [d/l] [select] |
by strat (Canon) on Jul 27, 2003 at 10:51 UTC | |
The script is a webserver that deals with the scheme of a directory service. At the starting of the program, the list is empty, and then with the first connection to the directory, the list is initialized according to the object classes and their settings (like attributes-names and their status (mandatory or optional), format, ...). The scheme of the directory changes sometimes, and the script will recognize these changements automatically and adapt the object interface methods to them. The calls to these objects are generated by user input, so some objectclasses may not be used for a long time, while others are used very often. And with autoload, I can get easy error messages if somehow an object interface method is called that is not allowed. The problem with AUTOLOAD and inheritance is no problem in this case.
Best regards, | [reply] |
by Anonymous Monk on Jul 31, 2003 at 00:48 UTC | |
|
Re: is autoload bad style?
by ihb (Deacon) on Jul 26, 2003 at 18:39 UTC | |
Update: As adrianh and Aristotle pointed out there is a module, NEXT, to cope with this. But NEXT has some issues of its own and is slow. (See "Bugs and irritations" in the documentation.) Having to pull in another module just proves my point: unless you really need AUTOLOAD, try to stay away from it. It may very well create more problem than it tries to solve. I've never really needed AUTOLOAD, although I've found some nifty (and "useful") uses for it. (That doesn't mean there aren't any cases where it is needed.) I try to avoid AUTOLOAD in object oriented code. There are two subtile traps that I'll try to explain here. The problem applies to all AUTOLOADs that don't want to do anything useful for all invokations of it. As example I'll use the popular concept of autogenerating attribute methods, which is particulary nice as an example as there would be no problems if the methods was pre-generated instead. (See Re: Re: is autoload bad style? for an elaboration on this.) Issue 1
This is your standard attribute AUTOLOAD routine customized to illustrate my point. It works as expected:
Now let's inherit Foo, and use the same technique in the child.
This too seems to work as expected:
But it doesn't quite work right when trying to use Foo's attributes:
So apparently we need to patch &Foo::Bar::AUTOLOAD.
Now it's suddenly not that pretty anymore, and not fully transparent. There is a caller backtrace issue. An error message about missing attribute will probably (and should, imho) point at the return line in &Foo::Bar::AUTOLOAD rather than where it really is invoked by the programmer. You could wrap the call in an eval BLOCK and propagate the error. But I wouldn't call that elegant. We can't use goto(), because then $AUTOLOAD won't be set in the target &AUTOLOAD. You could perhaps manually find where SUPER::AUTOLOAD is, and manually set $AUTOLOAD. But then it gets even uglier. As a parenthesis: return if $m eq 'DESTROY'; is bad in the general case if we should be strict. There's no guarentee that no super-autoload wants to deal with it. For me, this is enough to avoid AUTOLOAD and think of it as the very last resort. But wait, there's more. Issue 2 This problem has to do with multiple inheritance. We start by defining two simple classes that use AUTOLOADed attribute methods, as above. As in issue 1 this issue applies to all AUTOLOAD routines that have some criteria for when it should do anything useful.
Just as before, they seem to work alright:
Now, let's inherit both A and B.
Now we expect both AB::->xism and AB::->yism to work.
But nope. The explanation is that there's no way for an AUTOLOAD to tell perl that "oh, no, sorry, ignore me". Perl never gets a chance to discover &B::AUTOLOAD. I consider these two issues quite severe, and therefore I tend to frown upon AUTOLOAD. If one takes these two issues into consideration the coolness of AUTOLOAD is reduced--at least for me. I'm not totally anti-AUTOLOAD but I think it should be used with caution. Hope I've helped,ihb | [reply] [d/l] [select] |
by adrianh (Chancellor) on Jul 26, 2003 at 18:55 UTC | |
| [reply] | |
by Aristotle (Chancellor) on Jul 26, 2003 at 20:24 UTC | |
| [reply] | |