Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Bug or inconsitency? FQN of Package and sub name identical

by strat (Canon)
on Nov 22, 2007 at 15:12 UTC ( [id://652383]=perlquestion: print w/replies, xml ) Need Help??

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

Good morning,

I found a strange behaviour of perl when a function has the same fully qualified name as a package name. Here a shortened example:

Code 1: fails

#! /usr/bin/perl use warnings; use strict; package ABCconf; sub Query { my( $package ) = caller; print "Query called from $package\n"; my $x = ABCconf::Query->new(); } sub Insert { print "Insert called\n"; my $x = ABCconf::Query->new(); # <= problem: calls ABCconf::Query +and then on its output ->new } # Insert package ABCconf::Query; sub new { my $class = shift; print "New called: $class\n"; return bless {}, $class; } # new package main; ABCconf::Query(); print "-" x 60, "\n"; ABCconf::Insert();

Output:

D:\>perl testBug.pl Query called from main New called: ABCconf::Query ------------------------------------------------------------ Insert called Query called from ABCconf New called: ABCconf::Query New called: ABCconf::Query=HASH(0x226290) Attempt to bless into a reference at testBug.pl line 24.

If I put the sub Insert before sub Query, everything works as expected.

Code 2: works

#! /usr/bin/perl use warnings; use strict; package ABCconf; sub Insert { print "Insert called\n"; my $x = ABCconf::Query->new(); } # Insert sub Query { my( $package ) = caller; print "Query called from $package\n"; my $x = ABCconf::Query->new(); } package ABCconf::Query; sub new { my $class = shift; print "New called: $class\n"; return bless {}, $class; } # new package main; ABCconf::Query(); print "-" x 60, "\n"; ABCconf::Insert();

Output:

D:\>perl testBug.pl Query called from main New called: ABCconf::Query ------------------------------------------------------------ Insert called New called: ABCconf::Query

I know it isn't a good idea to use the same fully qualified name for a package or a sub, but I can't change it. Is this a bug, an inconsistency or a feature?

Testet with

D:\>perl -v This is perl, v5.8.8 built for MSWin32-x86-multi-thread (with 18 registered patches, see perl -V for more detail) Copyright 1987-2007, Larry Wall Binary build 822 [280952] provided by ActiveState http://www.ActiveSta +te.com Built Jul 31 2007 19:34:48 ...

Best regards,
perl -e "s>>*F>e=>y)\*martinF)stronat)=>print,print v8.8.8.32.11.32"

Replies are listed 'Best First'.
Re: Bug or inconsitency? FQN of Package and sub name identical
by ikegami (Patriarch) on Nov 22, 2007 at 19:32 UTC

    When barewords are involved like in

    print(foo + 2);

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

    print(foo(+2));

    but if foo's prototype is ($), it'll take that as a hint that you meant

    print(foo() + 2);

    It's the same for

    Foo->method();

    Perl usually guesses the above means

    "Foo"->method();

    but if Foo is a function, it'll take that as a hint that you meant

    Foo()->method();

    where Foo is presumably a function that returns a class name or an object.

Re: Bug or inconsitency? FQN of Package and sub name identical
by swampyankee (Parson) on Nov 22, 2007 at 15:28 UTC

    Odd behavior when package and sub names are identical? My first suggestion is "don't do that." Perl is probably resolving its subs based, at least partly, on which ones it sees first, so it will use the first one it finds. I don't think this is either a bug or an inconsistency; it's a design decision. It does mean that the order subs are defined matters, which is not a concern unique to Perl: quite a few linkers do the same thing.


    emc

    Information about American English usage here and here.

    Any Northeastern US area jobs? I'm currently unemployed.

      Yes, Foo-> compiles to (&Foo())-> if a sub Foo already exists; otherwise it's ("Foo")->:
      $ perl -wl sub Foo::new{"new in Foo"} sub Bar::new{"new in Bar"} print "before sub Foo: ", Foo->new; sub Foo {"Bar"} print "after sub Foo: ", Foo->new __END__ before sub Foo: new in Foo after sub Foo: new in Bar
      You can disambiguate by saying Foo::->new or "Foo"->new. I prefer the former.
Re: Bug or inconsitency? FQN of Package and sub name identical
by Sidhekin (Priest) on Nov 22, 2007 at 16:25 UTC

    Just make it clear to Perl that the package name is a string, not a function. In other words, quote it:

    my $x = 'ABCconf::Query'->new();

    print "Just another Perl ${\(trickster and hacker)},"
    The Sidhekin proves Sidhe did it!

Re: Bug or inconsitency? FQN of Package and sub name identical
by dsheroh (Monsignor) on Nov 22, 2007 at 15:31 UTC
    Personally, I'm inclined to call it a bug, as it violates the principle of least surprise - behaving differently based on the order in which subs are defined is a very surprising behaviour. I consider inconsistencies to be a category of bug, so those two options are equivalent, IMO. And I can't imagine how it could possibly qualify as a feature, so "bug" is really the only option left.

    However, I consider it to be a bug in the code which reuses the name much more so than a bug in perl itself. It's an excellent example of why one should follow the standard Perl convention of using InitialCaps for module names and all_lowercase for sub names, or at least follow some convention which distinguishes the two types of names. If a programmer chooses to name things ambiguously and gets bitten by that ambiguity, I'd say he deserves the pain that results. Unfortunately, that pain is more often felt by an innocent maintenance programmer rather than by the one who caused the problem in the first place.

Re: Bug or inconsitency? FQN of Package and sub name identical
by Anonymous Monk on Nov 22, 2007 at 15:49 UTC
    use my $x = ABCconf::Query::->new();
Re: Bug or inconsitency? FQN of Package and sub name identical
by props (Hermit) on Nov 23, 2007 at 13:39 UTC
    From Camel book,Chapter 8 (References) page 248.
    
    ..the parser will get confused if you define your own subroutines named as package name.(Which is why people typically stick with lowercase names for subroutines and uppercase for modules.)

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (1)
As of 2024-04-24 14:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found