If you're adept, you can use them to install subroutines on the fly, the first time they're called (instead of compiling everything at the beginning). Not only does that save you a bit of typing if you have many similar methods (accessors -- get_variable, set_variable), but if your program only uses a few at a time, you get a bit of a speed benefit.
If you were really tricky-minded, you could add new subroutines on the fly, with some eval magic. Rough, untested code follows, as I'm not completely positive of the AUTOLOAD syntax without checking a book:
sub AUTOLOAD {
next if $AUTOLOAD =~ /DESTROY/; # be safe
my $sub_text = shift;
$AUTOLOAD =~ s/.*:://;
eval qq|*{$AUTOLOAD} = sub { $sub_text };|
# the following goto may require
# no strict 'refs';
goto &$AUTOLOAD;
}
That's deep magic, and you'd better understand exactly what it does before you even think about using it. (There are only a couple of situations where I'd consider using it, and it would most definitely NOT be available to anyone off the street. Big security risk here.)
Update: I added the goto line because jlistf made me think of it. | [reply] [d/l] |
so... you're using the AUTOLOAD subroutine to create a new function by sending it the code you want it to perform. (note: you can also use the goto to actually turn it into a function in the symbol table, case you didn't know.) interesting. i'm not sure that i'd ever use it, but i suppose it might come in handy somehow.
y'know, you might be able to use this to add a subroutine to a running application without stopping it and restarting it... hmmm... any thoughts on that?
| [reply] |
In Object Oriented Perl, Damian Conway makes good use of AUTOLOAD to create accessor methods for object attributes on the fly.
Also, in CGI.pm many of the HTML helper functions are created using AUTOLOAD. This means that the script can generate a new HTML tag without a new version of the module being required.
--
<http://www.dave.org.uk>
European Perl Conference - Sept 22/24 2000, ICA, London
<http://www.yapc.org/Europe/>
| [reply] |
There can be a significant perfomance penalty for using
AUTOLOAD on OOP get/set functions however. It really
depends on the objects purpose. We had some get/set routines
autoloaded for database objects. So a autoloaded get/set function would get
called for each record of each row that got returned, and it
sucked majorly. By removing the autoloading and just accessing the data
structure directly we increased the peformance by over 20 times (over a minute to about 3 seconds).
But AUTOLOADING is great for objects where the get/setting is
not a significant process. And I love it for those lazy
days of hacking out proof-of-concept stuff in the OOP world.
| [reply] |
This is generally true, but there is an example in
Conway's book where he uses AUTOLOAD for accessor methods, but creates a new method on the fly, so that AUTOLOAD is only called the first time that a particular method is used.
The code looks like this (note use of no strict to allow symbolic references in a strictly (no pun intended) controlled manner.)
Should probably point out that this isn't actually Damien Conway's code, but a slightly changed version that I hacked up.
sub AUTOLOAD {
no strict 'refs';
my ($self, $val) = @_;
my ($name) = $AUTOLOAD =~ m/.*::(\w*)/;
*{$AUTOLOAD} = sub { return @_ > 1 ?
$_[0]->{$name} = $_[1] :
$_[0]->{$name}};
return defined $val ? $self->{$name} = $val : $self->{$name};
}
--
<http://www.dave.org.uk>
European Perl Conference - Sept 22/24 2000, ICA, London
<http://www.yapc.org/Europe/> | [reply] [d/l] |
Cool, this is a very good idea for accessors. Thanks davorg (and Damien).
I think I will start tweaking the code we have here to match.
But for our problem mentioned before (the DB result objects)
the overhead of the funtion calls alone vs directly access
the data structure was twice as slow. I tested by actually
creating the accessors without the use of AUTOLOAD.
But that is the price to pay for OOP modularity, and generally
well worth the performance price.
| [reply] |
i just found another use. something called delegation. if one module gets called with an unknown method, the AUTOLOAD function can automatically call that same method from a different module. check out advanced perl programming from O'Reilly for more info. | [reply] |