Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Re: Use of AutoLoader in Modern Times (future)

by tye (Cardinal)
on Nov 16, 2012 at 00:27 UTC ( #1004087=note: print w/ replies, xml ) Need Help??


in reply to Use of Autoloader in Modern Times

Thankfully, AutoLoader and similar modules have been becoming less widely-used. Having repeatedly seen code that takes way too long to load all of the tons of modules that eventually get used, my experience is that the slow loading is always due to a bunch of initialization that is being done too soon, not due to the time required to read and compile the code for subroutines. Though I've often seen people making the assumption that it was the time to read and compile the modules' code that was to blame. (See Devel::Init for my suggestion for how to avoid doing even slightly costly initialization too soon, or too late.)

So I suspect that the creation of modules for delaying the loading of module code may have been significantly motivated by flawed assumptions.

The worse problem with AutoLoader is that it is applied to a module via inheritance, which was just a horrible idea. Autoloading is not a property that should be inherited. If class X autoloads and class Y inherits from class X, it is simply a mistake for class Y to get impacted by class X's decision to use autoloading.

This is made even worse by AutoLoader giving a particularly bad error message for the case of a mispelt method name. Now calling Y->foo() when I meant to call Y->food() tells me that I installed the Y module incorrectly because I clearly left out the Y/foo.al file (when all that I left out was the letter 'd' in my code).

And this is made even worse by the twin design mistakes of having DynaLoader 1) use AutoLoader, and 2) be used via inheritance.

And aspects of this are also made worse by the fact that Perl has great support for using a module that makes changes that have to be made at compile-time (because they impact the syntax of the following code) but has awkward support for using modules that don't need to make changes at compile time.

It would be very nice for require to be enhanced so that it can be used more like use and also be more useful for loading OO modules. That is, require should be extended so that it can be used both of these ways:

# You must 'use' here, since new syntax is being defined: use My::Exceptions qw< try catch >; # New syntax: try { ... } catch { + ... } # You can 'require' here, since no impact on syntax: require My::Utils qw< min max zip >; # Parens required (no new syntax) when calling min(), max(), or zip(). my $logger = require My::Logger( -trace => 1 ); # Object returned (maybe a factory)!

And then it should be a decision based on the environment as to whether 'require' actually loads the module code at run-time or at compile-time. I'd default to loading at run-time and then having a "test dependencies" step that happens relatively frequently (at least before deploying and after deploying) that specifies "load all dependencies at compile-time" and then pretty much just exits.

I plan to make a proof of concept of "better 'require'" under a different name ('load'?) but also to push for Perl's own 'require' to get better in parallel (in my "copious free time").

- tye        


Comment on Re: Use of AutoLoader in Modern Times (future)
Download Code
Re^2: Use of AutoLoader in Modern Times (future)
by tobyink (Abbot) on Nov 16, 2012 at 14:57 UTC

    Module::Runtime's use_module function may be to your liking...

    use_module('My::Utils')->import(qw< min max zip >); my $logger = use_module('My::Logger')->new(-trace => 1);

    Update:... some people may well consider this insane but...

    BEGIN { package PerlX::qm; no thanks; sub import { my ($me, $name) = @_; require Module::Runtime; require PerlX::QuoteOperator; PerlX::QuoteOperator->new->import($name || "qm", { -parser => 1, -with => sub ($) { Module::Runtime::use_module(grep /\w/, split /\s/, $_[ +0]) }, }, scalar caller); } }; use 5.010; use strict; use warnings; use PerlX::qm; say qm( Math::BigInt 1.000 )->new('4660')->as_hex; say qm( Math::BigFloat )->new('74565')->as_hex;

    PerlX::qm defines a quote-like operator (like qq, qw or qx) for module names. Quoted modules are loaded at runtime, and can be followed by an optional version number.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1004087]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (6)
As of 2014-12-28 09:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (180 votes), past polls