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

I am working on a project where I have to read list of
environment variables from configuration file and
execute perl “eval” to expand the environment variable
and write it to new file.
I have a condition,
(defined $ENV{HOST} ? $ENV{HOST} : 'SQLHOST')
if HOST is not defined garb a string.
So I tried following making environment variable HOST undefined which work,
my $val; my $stmt = q{$val = (defined $ENV{HOST} ? $ENV{HOST} : 'sqlhost')}; eval $stmt; if ($@) { print $@, "\n"; } else { print $val, "\n"; }
OUTPUT= "sqlhost"

But I am suppose to read the configuration file so I tried this,
my ($r, $stmt); while ($stmt = <DATA>) { eval $stmt; print "$stmt\n"; if ($@) { print $@, "\n"; } else { print $r, "\n"; } } __DATA__ $r = (defined $ENV{HOST} ? $ENV{HOST} : 'sqlhost')
OUTPUT= "$r = (defined $ENV{HOST} ? $ENV{HOST} : 'sqlhost')"

it didn;t work can any one suggest me better solution?
Thanks

Replies are listed 'Best First'.
Re: eval, Read environment variable and expand using eval
by toolic (Bishop) on Feb 19, 2010 at 02:45 UTC
    it didn;t work
    Please elaborate. It seems to work for me when I run your 2nd code example. Here is the output I get:
    $r = (defined $ENV{HOST} ? $ENV{HOST} : 'sqlhost') sqlhost
    What do you expect the output to be? First, you print the statement verbatim, then you print the eval'd statement. I do not have the HOST variable set.
      There must be something which I don't know, In second code the output I am getting is,
      $r = (defined $ENV{INFORMIXSQLHOSTS} ? $ENV{INFORMIXSQLHOSTS} : 'sqlhost')
      But I am expecting,
      sqlhost
      which I am getting from first code. Cheers, Thanks
        You should be getting that since you're printing $stmt. You should *also* be getting the value of $ENV{HOST} or sqlhost.

        There is a subtle yet important difference between defined and exists on hash and array elements. Defined will autovivify your hash element and make its value undefined.

        Perhaps you meant this?

        $r = (exists $ENV{INFORMIXSQLHOSTS}) ? $ENV{INFORMIXSQLHOSTS} : 'sqlho +st')

        If you want to check every possiblity this would be the best. However I usually just do the exists() check.

        $r = ((exists $ENV{INFORMIXSQLHOSTS} && defined($ENV{INFORMIXSQLHOSTS} +) && length($ENV{INFORMIXSQLHOSTS}) ) ? $ENV{INFORMIXSQLHOSTS} : 's +qlhost'));
Re: eval, Read environment variable and expand using eval
by rovf (Priest) on Feb 19, 2010 at 10:06 UTC
    I have to read list of environment variables from configuration file and execute perl “eval” to expand the environment variable
    I don't understand why you need eval to get the value of an environment variable. If you have the name of the variable stored in $envvarname, you get the value with $ENV{$envvarname}. Maybe it would help if you can show an example of your configuration file.

    -- 
    Ronald Fischer <ynnor@mm.st>
Re: eval, Read environment variable and expand using eval
by AnomalousMonk (Archbishop) on Feb 19, 2010 at 13:03 UTC
    while ($stmt = <DATA>) { eval $stmt; ... }

    Yikes!

    Surely, the two most important rules of using  eval on data are:

    • Never  eval a string of data unless the data are absolutely trusted;
    • Never absolutely trust data.

    Per rovf's reply, isn't there another way to parse your config file, or to structure your config file so it may be more easily parsed?

    Update: Changed some emphases.

      Is the data produced by your source code editor, or that of your collegues, to be absolutely trusted?

      How about the data you download from CPAN and process with your perl executable?

        Lame strawman, put it in module, write tests, verify ...