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

Hi there,
the following code is giving me an error:
$Threscount=0; open(THRESHOLDS, "$Thresholds") or die("Could not open Thresholds file +."); foreach (<THRESHOLDS>) { chomp($_); if ($_ =~/^(\w+);(\d+);$/ && $_ !~/^\#/) { print "DEBUG: use constant $1 => $2;\n"; use constant $1 => $2; log_msg("Setting: use constant $1 => $2;"); if ($Threslabels[$Threscount] ne $1) { log_msg("There is something wrong with the thresholds labels, check + thresholds file!"); exit(2); } $Threscount++; } } if ($Threscount != 8) { print "$Threscount\n"; log_msg("Wrong number of thresholds they should be 8 there are $Thres +count"); exit(2); } close(THRESHOLDS);

Constant name '' is invalid at ./ line 75
BEGIN failed--compilation aborted at ./ line 75.
Thanks monks.
Nuno A

Further Details
Im trying to read the thresholds from a file since im going to compile de the script with pp it would be easier to have a wana be conf file.
Trying to substitute this dynamically:
#Define Warning values use constant SIMULWAR => 30; use constant MEMINUSEWAR => 200000000; use constant SIMULSNAGWWAR => 40; use constant CONDBWAR => 200; #Define Critical Values use constant SIMULCRIT => 50; use constant MEMINUSECRIT => 240000000; use constant SIMULSNAGWCRIT => 60; use constant CONDBCRIT => 240;

Replies are listed 'Best First'.
Re: Define constant in loop
by artist (Parson) on Feb 23, 2005 at 16:23 UTC
    Constant are set at compile time, rather than run time. There is no value for $1 in 'use constant $1=> $2' yet.
      Hmm I see,
      thank you for your answer.
      Best Regards,
      Nuno A
Re: Define constant in loop
by dragonchild (Archbishop) on Feb 23, 2005 at 18:04 UTC
    (Try answering the question vs. saying it can't be done! Grrr.)

    As use is a compile-time statement, you will need to use eval to do this at run-time.

    foreach (<THRESHOLDS>) { chomp($_); if (my ($name, $value) = $_ =~/^(\w+);(\d+);$/ && $_ !~/^\#/) { eval "use constant $name => $value;"; log_msg("Setting: use constant $name => $value;"); if ($Threslabels[$Threscount] ne $name) { log_msg("There is something wrong with the thresholds labels, check + threshold +s file!"); exit(2); } $Threscount++; } }

    Also, note that I changed your use of $1 and $2 by assigning them to normal variables. This is a safety as well as documentation thing.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

Re: Define constant in loop
by TedYoung (Deacon) on Feb 23, 2005 at 16:34 UTC

    Also note that constant won't let you declare constants like $1. These kinds of variables have special properties and declaring them constant would be a bad thing, if even possible.

    And constants are not used like normal variables:

    # You don't declare a constant like this: use constant $FOO => 1; # bad # You do it this way use constant FOO => 1; # And use it like this: print FOO;

    Ted Young

    ($$<<$$=>$$<=>$$<=$$>>$$) always returns 1. :-)
Re: Define constant in loop
by Tanktalus (Canon) on Feb 23, 2005 at 17:58 UTC

    Now that everyone has told you why it doesn't work, here's one solution to getting it to work:

    if ($_ =~/^(\w+);(\d+);$/ && $_ !~/^\#/) { print "DEBUG: use constant $1 => $2;\n"; eval "use constant $1 => $2"; #...
    The idea is to use $1 as a bareword, and $2 similarly. Note that this doesn't work so hot if $2 could be a string (which it isn't in your case). Unfortunately, it makes all your constants not easily accessable: you'll need to call them like MEMINUSEWAR() (with the parens) or similar. Barewords won't work.

    Another alternative is something like this:

    use strict; require constant; while (<DATA>) { if (/^(\w+);(\d+);$/) { #eval "use constant $1 => $2"; constant->import({$1 => $2}); } } print MEMINUSEWAR(); __DATA__ MEMINUSEWAR;2000000;
    Don't do that either. The best idea is to take all these values and put them in a hash - even a global hash. And access them through that.