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

Consider this code which is an attempt to create a CONSTANT which looks like variable, in this case $PIE.
use strict; *PIE = \"Warm Apple"; print "pie: $PIE\n";
However, strict is unhappy saying:
Variable "$PIE" is not imported at ./constant.pl line 7. Global symbol "$PIE" requires explicit package name at ./constant.pl l +ine 7. Execution of ./constant.pl aborted due to compilation errors.
Neglecting to use strict allows this to work.

Is there a way to declare constants that works under strict?

-------------------------------------
Nothing is too wonderful to be true
-- Michael Faraday

Replies are listed 'Best First'.
Re: How to create a "CONSTANT"
by kelan (Deacon) on Jun 05, 2003 at 23:11 UTC

    There's a pragma designed for constants. 'perldoc constant' for the manpage, but basically, it's like this:

    use constant PIE => "Warm Apple"; print "pie: ", PIE, "\n";
    Update: Fixed the typo from '=' to '=>' in the use line. Thanks merlyn.

    kelan


    Perl6 Grammar Student

Re: How to create a "CONSTANT"
by sauoq (Abbot) on Jun 05, 2003 at 23:27 UTC
    which is an attempt to create a CONSTANT which looks like variable
    use vars qw( $PIE ); *PIE = \"Warm Apple"; print "pie: $PIE\n";

    You were pretty specific, so I'm assuming you were already aware of use constant PIE => "Warm Apple"; which results in a constant sub that can't be interpolated into strings (easily.)

    -sauoq
    "My two cents aren't worth a dime.";
    
      they're not that difficult to interpolate:
      use constant PIE => "Warm Apple"; print "The value of PIE is @{[ PIE ]}.\n";

      which gives:

      The value of PIE is Warm Apple.

      --
      bowling trophy thieves, die!

        The reference-dereference trick works even with scalars (which is clearer, IMHO: we're a printing a scalar, not a sui generis array):
        print "The value of PIE is ${ \PIE }.\n";
Re: How to create a "CONSTANT"
by dpuu (Chaplain) on Jun 06, 2003 at 00:57 UTC
    If you really want a $const (not "use constant"), then I'd go with a tie:
    sub CONST::TIESCALAR { bless \(my $v = pop), shift } sub CONST::FETCH { ${(shift)} } tie $x, CONST => 4; print "$x\n"; $x = 7; # run-time error
    --Dave
      Thanks to kelan, perrin, sauoq, WBT, larsen, dpuu, and nite_man for the replies. You all were correct in assuming that I didn't want to use
      use constant PIE => "Warm Apple";
      I find
      print "The value of PIE is ${ \PIE }.\n";
      or even
      print "pie: ", PIE, "\n";
      not pleasing to read or write. The former is truly ugly, and the later looks a bit like a filehandle.

      Also, I have an existing code base with lots of scalar variables that are actually constants, so dpuu's solution is easiest to implement for me.

      Cheers

      --Fred


      Nothing is too wonderful to be true
      -- Michael Faraday
Re: How to create a "CONSTANT"
by perrin (Chancellor) on Jun 05, 2003 at 23:24 UTC
    You're talking about global variables, not constants. Globals must be declared with the vars pragma or fully-qualified.

    use strict; use vars qw($PIE); $PIE = 'Pumpkin'; print "pie: $PIE\n";
      You're talking about global variables, not constants.

      He's talking about old-school constants... (you know... the way we used to do it... back in the paradise garage...)

      $ perl -le '*PIE=\"Apple"; $PIE = "foo"' Modification of a read-only value attempted at -e line 1.

      Please excuse my Doc Martin impression.

      -sauoq
      "My two cents aren't worth a dime.";
      
Re: How to create a "CONSTANT"
by nite_man (Deacon) on Jun 06, 2003 at 06:49 UTC
    Try to look at How to use variables from other package?. This node help you create a package with your constants which you cwill able to use in your modules an scripts.
          
    --------------------------------
    SV* sv_bless(SV* sv, HV* stash);