jbazik has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks, I've just started using 5.10, and I noticed that, under 5.8:

% perl -e 'print defined %URI:: ? "yes\n" : "no\n";' no % perl -e 'print defined %URI:: ? "yes\n" : "no\n"; require URI;' no

but under 5.10:

% perl -e 'print defined %URI:: ? "yes\n" : "no\n";' no % perl -e 'print defined %URI:: ? "yes\n" : "no\n"; require URI;' yes

Do require's happen at compile time now?

Replies are listed 'Best First'.
Re: require at compile time?
by jwkrahn (Abbot) on Nov 06, 2008 at 23:27 UTC

    As reported in defined: "Use of defined on aggregates (hashes and arrays) is deprecated." so I wouldn't depend on your example producing a consistant result.

      exists $::{'URI::'} returns the desired result in both versions.
        As does exist exists $INC{'URI.pm'}

        Nice! Thanks.

Re: require at compile time?
by plobsing (Friar) on Nov 06, 2008 at 23:22 UTC

    The glob exists. But it's empty. So no.
    UPDATE: my understanding of symbol tables, globs, and compile-time inlining seems to be incorrect. Thank you ikegami for correcting me.

    $ perl -e 'print %URI:: ? "yes\n" : "no\n"; require URI;' no $ perl -e 'require URI; print %URI:: ? "yes\n" : "no\n"' yes

      The glob exists.

      What makes you think that? exists contradicts that.

      More likely, the guts were changed in a manner that either causes a reference (a defined value) to be passed to defined or causes %URI:: to be evaluated in scalar context (returning 0, a defined value).

        Regardless of the state of the guts, I guess that the question is: Why is the statement require URI;, which is executed after the print (and, more importantly, the defined test), changing the result of it? It must be that something in the mere compilation of require URI; is changing the execution of the rest of the program, right?

        I originally thought that it must be that the act of compilation creates the glob for future reference, but you say that this is not so. How do you use exists to test for the existence of a glob? (Is that what you're doing in Re^2: require at compile time? below?) According to the documentation, it can only be used on hash or array lookups, or subroutine names.