Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Bareword Package Names

by martin (Pilgrim)
on Aug 08, 2012 at 12:30 UTC ( #986250=perlquestion: print w/ replies, xml ) Need Help??
martin has asked for the wisdom of the Perl Monks concerning the following question:

This is a question about a perl5 feature I could find no documentation about so far. I would be glad to know whether it is intended this way and safe to use or even recommended.

A bareword ending in a double colon, such as Foo::Bar::, evaluates to a string without the double colon suffix, "Foo::Bar" in this example. Using such a bareword is not prohibited under strict 'subs', but it triggers a warning if perl hasn't seen a package of that name yet.

Example:

use strict; use warnings; package Foo::Bar; package main; my $p = Foo::Bar::; print "$p\n"; # prints Foo::Bar my $q = Baz::Qux::; # warns: # Bareword "Baz::Qux::" refers to nonexistent package print "$q\n"; # prints Baz::Qux

I'll call this feature package-name-quoting, as appending two colons has the effect of quoting plus package name validation. I could use it where package name strings are needed, such as in arguments for isa or DOES. The warning would help me to catch typos.

So, after all, it is a useful feature. Is it documented? I would have expected perlmod to say something about it. Maybe I looked in the wrong place.

Comment on Bareword Package Names
Download Code
Re: Bareword Package Names
by tobyink (Abbot) on Aug 08, 2012 at 14:08 UTC

    I'm not sure how documented the behaviour you describe is, but the trailing double colons have another use. Consider the following:

    use 5.010; { package Foo; sub new { bless [] } sub Bar { 'Quux' } } { package Foo::Bar; sub new { bless [] } } { package Quux; sub new { bless [] } } my $object1 = Foo::Bar::->new; say ref $object1; # says "Foo::Bar" my $object2 = Foo::Bar->new; say ref $object2; # says "Quux"
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

      What tobyink demonstrated is that a bareword will act as a procedure call if (and only if) a subroutine of that name is known. Perl's auto-quoting of barewords will only kick in in the absence of such a subroutine. Any kind of explicit quoting, of course, will also avoid procedure calls.

      my $object3 = 'Foo::Bar'->new; say ref $object3; # says "Foo::Bar"

      So we now have established by different examples that trailing double-colons can act like quoting.

      There may be caveats though. In some places where perl looks for barewords, the package-quoted bareword does not seem to lose its bareword-likeness.

      use strict; use warnings; package Foo::Bar; package main; print Foo::Bar::; # warns: # Name "Foo::Bar" used only once: possible typo # print() on unopened filehandle Bar print Foo::Bar::, "Baz\n"; # prints Foo::BarBaz

      Perl has to distinguish whether print with a single argument is called as print HANDLE or print LIST, and apparently uses a rather simple heuristic for this.

      I try to avoid ambiguity with print and always use the print HANDLE LIST syntax for printing to handles.

        See Programming Perl 4th Edition page 389 - Symbol Tables.

        "Symbol tables are stored in a hash whose name is the same as the package, but with two colons appended. The main symbol table's name is thus %main::."

        "Likewise, the symbol table or the Red::Blue package is named %Red::Blue::."

        James

        Also see page 423 - Package-Quoted Classes.

        "The final syntactic ambiguity with the indirect object style of method invocation is that it may not be parsed as a method call at all, because the current package may have a subroutine of the same name as the method...there is a way to resolve this ambiguity while still keeping the indirect object syntax: package-quote the class name by appending a double colon to it."

           $obj = method CLASS::;   # forced to be "CLASS"->method
Re: Bareword Package Names
by tobyink (Abbot) on Nov 27, 2012 at 12:53 UTC

    Interestingly...

    use Test::More tests => 1; # this test fails is( do { package Foo::Bar::; __PACKAGE__ }, do { package Foo::Bar; __PACKAGE__ }, );

    So there's at least one place the barewords Foo::Bar:: and Foo::Bar evaluate to different packages.

    See also, Perl allows package names consisting entirely of colons.

    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: perlquestion [id://986250]
Front-paged by Corion
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-25 06:57 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

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





    Results (159 votes), past polls