I get the following warning:
"Use of uninitialized value in concatenation (.) or string at C:\tools\test.pl line 17, DATA line 1."
But the next line of __DATA__
will be processed without any warning and get these:
test1b.txt:test test1c.txt:test :test
More strange thing is that when I add a line: print "$line:".$'."\n";
The warning disappeared.
Anybody have some clues?
#!/usr/bin/perl -w
use strict;
my $pattern='test';
my $output='$&';
while(<DATA>)
{
chomp;
my $line=$_;
chomp($line);
$line=~/$pattern/;
#print "$line:".$&."\n"; #why uncommenting this line make the following line pass without no warning.
my $result="$line:".eval($output)."\n";
print $result;
}
__DATA__
test1a.txt
test1b.txt
test1c.txt
In a string eval, the value of the expression (which is itself determined within scalar context) is first parsed, and if there were no errors, executed as a block within the lexical context of the current Perl program. This form is typically used to delay parsing and subsequent execution of the text of EXPR until run time.
During this time, if the block of perl code is executed inside the eval, then program continues to run even after the die or errors, and it also captures the errors or dieing words. In the above, $count contains the value as 0.
It is also Perl's exception-trapping mechanism, where the die operator is used to raise exceptions. Before Perl 5.14, the assignment to $@ occurred before restoration of localized variables, which means that for your code to run on older versions, a temporary is required if you want to mask some, but not all errors:
So, we can write the dynamic perl program using eval. We can execute any number of statements in eval. The result of the eval is the last evaluated expression. We should be care in using eval on a string, as it might execute untrusted data from a string.
Perl considers $&
, $'
, and $`
to be expensive, so it won't actually populate them in a program that doesn't use them. From the perlvar
manpage:
The use of this variable [
$&
] anywhere in a program imposes a considerable performance penalty on all regular expression matches. To avoid this penalty, you can extract the same substring by using@-
. Starting with Perl 5.10, you can use the/p
match flag and the${^MATCH}
variable to do the same thing for particular match operations.
However, when you only use them inside a string that you pass to eval
, Perl can't tell that you're using them, so it won't populate them, so they'll be undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With