http://qs321.pair.com?node_id=598856

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

Dear Brethren, most of us have used code like this:
use constant DEBUG => 1; use constant SOMETHINGELSE => 'key';
This looks fine. However, let's look at this quote from perlsub:
       Subroutines whose names are in all upper case are reserved to the Perl
       core, as are modules whose names are in all lower case.  A subroutine
       in all capitals is a loosely-held convention meaning it will be called
       indirectly by the run-time system itself, usually due to a triggered
       event.  Subroutines that do special, pre-defined things include
       "AUTOLOAD", "CLONE", "DESTROY" plus all functions mentioned in perltie
       and PerlIO::via.
Now, we all know that constant.pm translates constant names into subroutines... The question is: do we violate Perl conventions by using upper-case constant names? Is that one of those cases where syntactic sugar hurts?

Update: The question has been answered here.

Replies are listed 'Best First'.
Re: Constant names come into conflict with Perl style?
by reyjrar (Hermit) on Feb 07, 2007 at 19:17 UTC
    Which is why you might want to investigate the Readonly module.
    use Readonly; Readonly::Scalar my $DEBUG => 1;
    -brad..
      That might be a fine module and I'll check it out, but it does not answer the question posed: is this commonly accepted practice of using upper-case constant names directly clash with another commonly accepted practice of not naming subroutines in all caps?

        constant.pm actually is creating subroutines. I picked up a copy of Perl Best Practices, in which Damian Conway recommends Readonly.pm for the exact reasont that you stated.

        I'm not sure what you're looking for here. The "best practices" are constantly evolving as new and interesting modules enter the fray. Program the way that makes sense to you. Following best practices is encouraged but not required and not always the best solution.

        Typically uppercase subroutines signify that they'll be called by some internals. This isn't set in stone as heredocs and labels typcially use all caps as well. Generally you need to establish context to determine how in accordance with best practice a particular piece of code is.

        It makes sense for a constant to be a variable, which is why I like Readonly. I have run into issues where a Readonly array is actually useful. It doesn't happen daily, but when it does rear it's head, I like to address it with Readonly.pm rather than some copying hack.

        If you want to get into the philosophy of when and where to hold down shift, perhaps starting a thread on Meditations would be a better fit.

        -brad..
Re: Constant names come into conflict with Perl style?
by BrowserUk (Patriarch) on Feb 07, 2007 at 21:15 UTC

    There is nothing that says that your constant subs have to have all upper case names.

    My personal preference has evolved to be mixed case names starting with an upper case letter. This avoids the conflict you describe, and (in my schema), distinguishes constant subs from other subs which are mixed case but start with a lower case letter.

    I also find it infinitely preferable to so called Readonly variables--which is just a nonsense IMO. (Ie. variables that don't). Constant subs also allow Perl to perform optimisations that are not possible with 'Readonly variables'; and they don't carry that modules overheads.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      "There is nothing that says that your constant subs have to have all upper case names."

      That's true, there's nothing that says it, but if you grep your /usr/lib/perl5 for 'use constant', you will see that the overwhelming majority of constant names are upper-case.

Re: Constant names come into conflict with Perl style?
by kyle (Abbot) on Feb 07, 2007 at 19:20 UTC

    I heard about Readonly before I heard about constant. I don't think I'd like constants that I can't stick into a double quoted string.

Re: Constant names come into conflict with Perl style? (_)
by tye (Sage) on Feb 07, 2007 at 23:18 UTC

    "SOMETHING_ELSE" isn't all upper case. I also think best practices indicate that you should avoid all-lower-case subroutine names because conflicts there are even more likely (unless you prefix your subroutine calls with &, something that likely gets you yelled at, usually for silly reasons such as "looks like Perl 4").

    If you can't think of a multi-word name for your constants, you could go with a Hungarian-ish lower-case prefix like "cDEBUG", as "DEBUG" certainly seems like something a future version of Perl might make use of. (:

    - tye        

      Better yet, the Apps-Hungarian-ish bDEBUG (except I think "b" was "bytes", not "boolean").



      If God had meant us to fly, he would *never* have given us the railroads.
          --Michael Flanders

Re: Constant names come into conflict with Perl style?
by sgt (Deacon) on Feb 07, 2007 at 23:14 UTC

    It is a good point. All caps subs are reserved, so it's better to use "constants" with at least a non-cap (underscore etc...).

    use constant MY_PACKAGE => 'blah blah'; use constant APPROX_PI => 3.1415926; use constant _PI_ => 3; # ugly?
    cheers --stephan
      All caps subs are reserved

      Unfortunately, at some point last year the Perl 5 Porters accidentally broke this rule. There was a problem with cloning in threaded environments, and a magic subroutine named CLONE_SKIP was ushered in to deal with it.

      Despite all the eyes of the people who worked on it, it escaped into the wild and it wasn't until a couple of months later that someone noticed that the name violated the guidelines (in that it really should have been called CLONESKIP).

      Such is life.

      • another intruder with the mooring in the heart of the Perl

        Thanks for pointing this out. I actually remember the discussion on p5p and it was interesting, see the CLONE_SKIP story.

        So the underscore is not so good actually :(. The next best thing could be a simple "postfix".

        use constant MYPACKAGE_c => 'Universe::Tiny'; use constant RWXu => 0700; use constant MYLOGGERc => \do{local *FH; *FH};

        Actually a postfix like "c" or "_c" (or even "const" if you don't feel lazy) is good *visually* to remember they are gotchas like remembering when {}ing is actually necessary! (stressed by PBP)

      • MYPACKAGE_c->factory();
      • print {LOGGERc} "important login data";
      • #!/usr/bin/perl use strict; use warnings; use constant LOGGERc => \do{local *FH; *FH}; # silence warnings open LOGGERc, ">mylog" or die; # gotcha print {LOGGERc} "info...", "\n" or die; print {\*STDOUT} qx(cat mylog);
        decent_shell% perl -MLWP::UserAgent -Mconstant=PKGc,LWP::UserAgent -e +'print +PKGc->new();'
        cheers --stephan
Re: Constant names come into conflict with Perl style?
by Snigwel (Sexton) on Feb 08, 2007 at 21:21 UTC
    From the camel, 3rd Ed. p.218:

    "Perl doesn't force a particular capitalization style on your subroutine names. However, one loosely held convention is that functions called indirectly by Perl's runtime system (BEGIN, CHECK, INIT, END, AUTOLOAD, DESTROY...)are in all capitals, so you might want to avoid using that style. (But subroutines used for constant values are customarily named with all caps too. That's okay. We hope...)"

    I tried arguing with a camel twice - the second time the excuse of curiosity invalidated, leaving stupidity as the only explanation...
      Beautiful! This answers my question to the 't'.