[comp.lang.perl] eval and ||

me@anywhere.EBay.Sun.COM (Wayne Thompson - IR Workstation Support SE) (11/25/90)

The following code opens /etc/passwd but fails to die on /etc/bogus.
Any ideas? (3.0pl41)

&PushFiles ('$passwd', '/etc/passwd'
    , '$bogus', '/etc/bogus'
);

for $file (@files) {
    ($fh = $file) =~ s/^\$//;
    eval ('
        open (' . $fh . ') || die "$MYNAME: error: ' . $file . ': $!\n";
    ');
}

sub PushFiles {
    local (@list) = @_;
    local ($fh, $file);
    while (($fh, $file, @list) = @list) {
        eval "$fh = '$file'";
        push (@files, $fh);
    }
}

piet@cs.ruu.nl (Piet van Oostrum) (11/28/90)

>>>>> In message <3991@male.EBay.Sun.COM>, me@anywhere.EBay.Sun.COM (Wayne Thompson - IR Workstation Support SE) (WT) writes:

WT> The following code opens /etc/passwd but fails to die on /etc/bogus.
WT> Any ideas? (3.0pl41)

WT> &PushFiles ('$passwd', '/etc/passwd'
WT>     , '$bogus', '/etc/bogus'
WT> );

WT> for $file (@files) {
WT>     ($fh = $file) =~ s/^\$//;
WT>     eval ('
WT>         open (' . $fh . ') || die "$MYNAME: error: ' . $file . ': $!\n";
WT>     ');
WT> }

WT> sub PushFiles {
WT>     local (@list) = @_;
WT>     local ($fh, $file);
WT>     while (($fh, $file, @list) = @list) {
WT>         eval "$fh = '$file'";
WT>         push (@files, $fh);
WT>     }
WT> }

I have three answers to this question:

1. A die inside eval does kill the eval but not the program. This is
because one of the uses of eval is to catch otherwise fatal errors.
In this case the errormessage from die will be put in the variable $@.
You can test this outside the eval.

2. Eval return the value of the expression it evaluates. So the || die can
just be put outside the eval:


for $file (@files) {
    ($fh = $file) =~ s/^\$//;
    eval ("open ($fh)")
	|| die "$MYNAME: error: " . eval ($file) . ": $!\n";
}

3. open can have a variable as file handle. Unfortunately, it does require
the second parameter then.
I personally prefer the following solution:

for $file (@files) {
    ($fh = $file) =~ s/^\$//;
    local($fname) = eval($file);
    open ($fh, $fname)
	|| die "$MYNAME: error: $fname : $!\n";
}
-- 
Piet* van Oostrum, Dept of Computer Science, Utrecht University,
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands.
Telephone: +31 30 531806   Uucp:   uunet!mcsun!ruuinf!piet
Telefax:   +31 30 513791   Internet:  piet@cs.ruu.nl   (*`Pete')