Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strange thing in perl's eval function

Tags:

perl

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
like image 281
user2462304 Avatar asked Jun 07 '13 06:06

user2462304


People also ask

What is a string Eval in Perl?

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.

What happens when Perl code is executed inside the eval?

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.

What is the use of $@ in Perl?

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:

How to write a dynamic Perl program using eval?

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.


1 Answers

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.

like image 109
ruakh Avatar answered Sep 24 '22 13:09

ruakh