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

Reply via email to