SPUG: conditional module loading

Joshua ben Jore twists at gmail.com
Sat Jul 14 21:48:42 PDT 2007


On 7/14/07, DeRykus, Charles E <charles.e.derykus at boeing.com> wrote:
> As another alternative,  you could just load at runtime
> before the call to print_id() occurs:
>
>    #!/usr/bin/perl
>    ...
>    if ( $ENV{ test_status } == 1 ) {
>        require TestMod;
>        import TestMod qw/print_id/;
>    elsif ( $ENV{ test_status } == 2 ) {
>        require Test2Mod;
>        import Test2Mod qw/print_id/;
>    ...
>    }

Oooh, argh! If you use the "method invocant args" syntax you're
semi-likely to get the wrong result especially if you end up with
method names in common. The most common thing to get wrong is "new," I
guess but I suppose import would easily be possible. That is... if
you're doing OO or writing a module.

The thing is, if during compilation perl sees an indirect object it
has to enter this nice bit of code. Here's the comments for
S_intuit_method in toke.c.

/*
 * S_intuit_method
 *
 * Does all the checking to disambiguate
 *   foo bar
 * between foo(bar) and bar->foo.  Returns 0 if not a method, otherwise
 * FUNCMETH (bar->foo(args)) or METHOD (bar->foo args).
 *
 * First argument is the stuff after the first token, e.g. "bar".
 *
 * Not a method if bar is a filehandle.
 * Not a method if foo is a subroutine prototyped to take a filehandle.
 * Not a method if it's really "Foo $bar"
 * Method if it's "foo $bar"
 * Not a method if it's really "print foo $bar"
 * Method if it's really "foo package::" (interpreted as package->foo)
 * Not a method if bar is known to be a subroutine ("sub bar; foo bar")
 * Not a method if bar is a filehandle or package, but is quoted with
 *   =>
 */

There's more rules scattered through toke.c. Here's more guessing on
the part of perl:

                    /* If not a declared subroutine, it's an indirect object. */
                    /* (But it's an indir obj regardless for sort.) */
                    /* Also, if "_" follows a filetest operator, it's
a bareword */

In short... using indirect object syntax is ambiguous and requires
perl to do a pile of work just to guess at what you mean. You *hope*
perl's guess matches your expectations. I certainly can't remember
that entire list of rules all the time.

The best, unambiguous syntax uses the pointy arrow.

TestMod2->import( ... )

Josh


More information about the spug-list mailing list