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

I have paste the same question on StackOverflow It is solved.

The following script get 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?

#file: test.pl #!/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 fo +llowing line pass without no warning. my $result="$line:".eval($output)."\n"; print $result; } __DATA__ test1a.txt test1b.txt test1c.txt

Replies are listed 'Best First'.
Re: strange thing in perl's eval function
by 2teez (Vicar) on Jun 07, 2013 at 07:39 UTC

    There are several things that are not efficient in your script as shown in your OP.

    1. why assign "matched" string before going over the string? Only to check it using an "eval" string.
    2. You are chomping the string twice for what reason?
      Why not do:
      while (my $line=<DATA>) { chomp($line);..
    3. finally, you don't want to be using $&, $' and $` in your program.
      Check perlfaq6 on your system as perldoc perlfaq6
      OR check Here
    Something like this could help:
    #file: test.pl #!/usr/bin/perl -w use strict; use v5.10; my $pattern = qr/test/; while (my $line=<DATA>) { chomp($line); $line =~ /($pattern)/p; my $result = $line. ' => matched:'.${^MATCH}.$/; print $result; } __DATA__ test1a.txt test1b.txt test1c.txt

    If you tell me, I'll forget.
    If you show me, I'll remember.
    if you involve me, I'll understand.
    --- Author unknown to me
      1. Just because if removing the first one, warning appears, an answer on StackOverflow has cleared this problem. 2. Because sometimes $_ changes unpredictable, I used another variable but forgot to remove the first chomp. 3. Good suggestion. I hope perl6 will mature soon, not just on VM.
Re: strange thing in perl's eval function
by choroba (Cardinal) on Jun 07, 2013 at 06:49 UTC
    Crossposted (and answered) at StackOverflow. It is considered polite to inform about crossposting, so that people not attending both sites do not waste their efforts solving a problem already solved at the other end of the Internets.
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      thanks for pointing that. Corrected.
Re: strange thing in perl's eval function (re match vars)
by Anonymous Monk on Jun 07, 2013 at 07:17 UTC

    Its because $' and $& are magic, and come with a performance penalty, and in general you shouldn't use them

    Also, you shouldn't use them without testing for sucess, without writing  if ( $line=~/$pattern/ ){ ... }

    Change  my $output= q{" $& | $'"}; and you'll get

    Use of uninitialized value $& in concatenation (.) or string at (eval +1) line 1, <DATA> line 1. Use of uninitialized value $' in concatenation (.) or string at (eval +1) line 1, <DATA> line 1.

    Add  local $&; on top of your program, that is mention $& in your code, and the penalty kicks in and the warning goes away

    Also, there might be a bug in there too, for example this doesn't trigger this warning

    #!perl -w $o = q{qq{ $& | $'}}; $p = q{.}; $_=1234; /$p/; print eval $o; __END__ 1 | 234
    But this does
    #!perl -w $o = q{qq{ $& | $'}}; $p = q{2}; $_=1234; /$p/; print eval $o; /$p/; print eval $o; __END__ Use of uninitialized value $& in concatenation (.) or string at (eval +1) line 1. Use of uninitialized value $' in concatenation (.) or string at (eval +1) line 1. | 2 | 34

    On a scale of importance from 1 to 10, I'd rate this bug a -3000 :)

        As choroba pointed out, this question is solved on StackOverflow

        Its a good thing this here is perlmonks, where relevant discussion is welcome :)