Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

use vs. require

by reneeb (Chaplain)
on Nov 27, 2007 at 15:05 UTC ( [id://653255]=perlquestion: print w/replies, xml ) Need Help??

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

Hi folks,

I've got one question:

test1.pl:

#!/usr/bin/perl use A; my $test = A::B->new(test => 1);

A.pm:

package A; sub B{ print "A::B called with args <@_>\n"; shift; return A::B->new(@_); } package A::B; sub new{ print "A::B::new called with args: <@_>\n"; return bless {}, shift; } 1

result:

A::B called with args <> A::B::new called with args: <A::B> A::B::new called with args: <A::B=HASH(0x23602c) test 1> Attempt to bless into a reference at A.pm line 14.

test2.pl:

require A; my $test = A::B->new(test => 1);

result:

A::B::new called with args: <A::B test 1>

I've search several docs, but haven't found anything that would explain why "use" and a "require" in a BEGIN block have a different behaviour than "require" or a "use"(in a string eval). Why is in one case the subroutine B called (when A is loaded in compile time) and in the other case the subroutine "new" of package A::B is called (when A is loaded in run time)?

Cheers,
Renee

Replies are listed 'Best First'.
Re: use vs. require
by ikegami (Patriarch) on Nov 27, 2007 at 15:35 UTC

    The problem is that A::B is both a package name and a sub name. The difference is whether or not Perl knows A::B is a sub when A::B->new() is compiled.

    When barewords are involved like in

    A::B->new()

    Perl must guess at what it means. Perl usually guesses the above means

    "A::B"->new()

    but if A::B is known to be a function, Perl will take that as a hint that you meant

    A::B()->new()

    where A::B is presumably a function that returns a class name or an object.

    So why does test1.pl know A::B is a function name while test2.pl doesn't? The order in which they compile sub A::B relative to A::B->new varies.

    test1.pl

    1. Compile use A; 2. Execute require A; 3. ... 4. Compile sub B { ... } 5. ... 6. Execute A->import(); 7. Compile my $test = A::B->new(test => 1); as A::B()->new 8. Execute my $test = A::B->new(test => 1);

    test2.pl

    1. Compile require A; 2. Compile my $test = A::B->new(test => 1); as "A::B"->new 3. Execute require A; 4. ... 5. Compile sub B { ... } 6. ... 7. Execute my $test = A::B->new(test => 1);

    Also see recent thread Bug or inconsitency? FQN of Package and sub name identical.

    PS - Please use <c>...</c> around your code instead of <pre>...</pre>. It handles escaping, auto-wrapping, and makes the code easier to download.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://653255]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-03-29 09:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found