Oh, and you sparked a memory.
LazyLoader.pm was an older one Schwern and I tried to build a couple of years ago which in theory could turn ANY code into lazyloading code by rewriting it on the fly at install time. :/
I believe he ran it on his entire perl install once and found an across the board 30%+ improvement.
Unfortunately, it got bogged down with closures and we could find a way to solve it that didn't involve parsing Perl without perl, which was impossible at the time ;)
It might bet reborn at some point once PPI is done, but I've included an old snapshot for posterity.
Adam
-----------------------------------------------
package LazyLoader;
$VERSION = 0.01; @EXPORT = qw(lazify); @ISA = qw(Exporter);
use strict; require Exporter;
our $MAXIMUM_IGNORE_SIZE = 100; # Set this to something better
sub lazify {
my $file = shift; # Does the file exist, and can we read and write it
return undef unless -f $file;
return undef unless -r $file;
return undef unless -w $file; # Slurp in the file
my $code;
{ local $/ = undef;
open( LAZYFILE, $file ) or return undef;
$code = <LAZYFILE>;
close LAZYFILE;
}sub lazify_content {
my $content = shift;# Use a basic state filter
my @out = ();
my $in_lazy_sub = 0;
my @lazy_sub = ();
my $lazy_count = 0;
my $line_num = 0;
my $starting_line = 0;
foreach my $line ( split /(?:\015{1,2}\012|\015|\012)/, $code ) {
$line_num++;
if ( $in_lazy_sub ) {
# Is this the last line?
if ( $line =~ /^}\s*$/ ) {
push @lazy_sub, $line;
# Do we need to lazify this?
if ( length(join '', @lazy_sub) > $MAXIMUM_IGNORE_SIZE ) {
# If this is the first time we've lazified something,
# define the warning sub we need to use.
unless ( $lazy_count++ ) {
push @out, "my \$__lazy_warn = sub { warn [EMAIL PROTECTED] unless join('',[EMAIL PROTECTED]) =~ /^Subroutine \$LazyLoader::name redefined at/; };";
}
# Add the lazified code
_add_lazified_sub( [EMAIL PROTECTED], [EMAIL PROTECTED],
$starting_line, $line_num )
or return undef;
} else {
push @out, @lazy_sub;
}
# Reset
$in_lazy_sub = 0;
@lazy_sub = ();
} else {
# Part of the lazy sub
push @lazy_sub, $line;
}
} else {
if (
$line =~ /^sub\b/ # The start of a sub?
and
$line =~ /{\s*$/ # It's not a prototype
and
$line !~ /}\s*$/ # It's not a one line sub
and
$line !~ s/\:\s*not_lazy\b// # We've been told to ignore it
) {
push @lazy_sub, $line;
$in_lazy_sub = 1;
$starting_line = $line_num;
} else {
# Normal line in the file
push @out, $line;
}
}
}
# Write the changed code back to the file
open ( LAZYFILE, ">$file" ) or return undef;
print LAZYFILE join "\n", @out;
close LAZYFILE;1; }
sub _add_lazified_sub {
my($out, $code, $starting_line, $ending_line) = @_;
return unless ref $out eq 'ARRAY';
return unless ref $code eq 'ARRAY';
# The first line of the lazy sub code contains the same sub definition,
# but we want to add our loading code to it.
my $firstline = $code->[0];
my ($name) = $firstline =~ /^sub.+?(\w+)/;
$firstline =~ s/\s+{.*//;
$firstline .= " { delete *$name; eval <<'LAZYLOAD_END'; goto &$name }";
push @$out, $firstline; push @$out, "#line $starting_line";
push @$out, @$code;
push @$out, 'LAZYLOAD_END';
push @$out, "#line ". ($ending_line + 1);
return 1;
}Stevan Little wrote:
Terrence,
There is also Class::LazyLoad <http://search.cpan.org/~rkinyon/Class-LazyLoad/> which Rob Kinyon and I wrote (actually 99% of it was Rob, I just wrote some of the test suite and added a few features). It is basically meant to be a very very lightweight alternative to things like Object::RealizeLater and Class::LazyObject (speaking of which you should add Class::LazyObject <http://search.cpan.org/~daxelrod/Class-LazyObject/> to your list).
BTW - What's with the Catalog::* namespace? You building something interesting you want to share with the rest of the group? :)
- Steve
On Jan 18, 2005, at 7:02 PM, Terrence Brannon wrote:
I think a list of modules which dynamically load packages and/or create objects at runtime would be useful. Please add any modules that you know of that I overlooked... also feel free to write a comprehensive assessment of these modules (grin).
NAME Catalog::lazy_loaders - list of all CPAN object/package lazy loaders
DESCRIPTION
A lazy loader allows a program to dynamically (i.e., at run-time, on
demand) load a package. I have seen several such modules make their way
onto CPAN and thought it would be beneficial to have a list of all of
them somewhere.
Ideally the features of these modules would be evaluated, but cataloging
the modules is a valuable first step.
RELATED MODULES * Object::RealizeLater by Mark Overmeer <http://search.cpan.org/dist/Object-Realize-Later/>
* Class::Autouse by Adam Kennedy <http://search.cpan.org/~adamk/Class-Autouse-1.14/>
* AnyLoader by Michael Schwern <http://search.cpan.org/search?dist=anyloader>
* Class::Loader by Vipul Ved Prakash <http://search.cpan.org/dist/Class-Loader/>
Note: this module got slagged on cpan ratings:
<http://cpanratings.perl.org/d/Class-Loader>
* load by Elizabeth Mattijsen <http://search.cpan.org/dist/load>
* Module::Load::Conditional by Jos Boumans <http://search.cpan.org/dist/Module-Load-Conditional>
* Class::Dynamic by Simon Cozens <http://search.cpan.org/dist/Class-Dynamic>
* require I suppose require in the Perl core deserves an honorable mention.
SEE ALSO For further discussion of this topic, please comment at the Perl software design mailing/GMANE list:
<http://www.metaperl.com/sw-design>
AUTHOR Terrence Brannon, <[EMAIL PROTECTED]>
COPYRIGHT AND LICENSE Copyright (C) 2005 by Terrence Brannon
This library is free software; you can redistribute it and/or modify it
under the same terms as Perl itself, either Perl version 5.8.4 or, at
your option, any later version of Perl 5 you may have available.
-- Carter's Compass: I know I'm on the right track when, by deleting something, I'm adding functionality.
_______________________________________________ sw-design mailing list [email protected] http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
_______________________________________________ sw-design mailing list [email protected] http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
_______________________________________________ sw-design mailing list [email protected] http://metaperl.com/cgi-bin/mailman/listinfo/sw-design
