Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Missing $ on loop variable

by superfrink (Curate)
on Dec 02, 2005 at 20:32 UTC ( [id://513713] : perlquestion . print w/replies, xml ) Need Help??

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

I am getting this message and I'm not sure why. Can someone explain this? Is perl 5.6 complaining that the "my" does not start with a "$" character?

Missing $ on loop variable at /home/chad/bin/tee-err-warn.pl line 40.

Line 40 has a foreach loop.
# find lines with keywords foreach my $i (@keywords) { ## -- LINE 40 -- if($line =~ m/$i/i) { # copy found lines to the found lines array push @found , $line; } }

The error only shows up on a solaris 2.5 machine, "v5.6.1 built for sun4-solaris". It does not show up on a hand full of other machines:
  • aix 4.3.3 "version 5.005_03 built for aix"
  • debian 2.1 "version 5.004_04 built for i386-linux"
  • solaris 2.8 "version 5.005_03 built for sun4-solaris"
  • fedora core 4 "v5.8.6 built for i386-linux-thread-multi"

I tried moving the "my $i" to it's own line and the error went away.
# find lines with keywords my $i; foreach $i (@keywords) { ## -- now LINE 41 -- if($line =~ m/$i/i) { # copy found lines to the found lines array push @found , $line; } }

Replies are listed 'Best First'.
Re: Missing $ on loop variable
by gu (Beadle) on Dec 02, 2005 at 21:01 UTC
Re: Missing $ on loop variable
by psychotic (Beadle) on Dec 02, 2005 at 21:09 UTC
    I'am almost confident this is a bug. How about the less verbose edition of this, which i'd use if i was writing the above code, which follows. Does it work?
    my @found; my $line = 'Alpha and some junk here'; my @keywords = qw(alpha beta gamma); foreach (@keywords) { $line =~ m/$_/i ? push @found, $_ : next } foreach (@found) { print }

      When I see a ternary used in that fashion, I can't help but imagine you're one step away from condensing that down to:

      $line=~/$_/i&&push(@found,$_)for@keywords;

      Myself, I'd expand it a bit:

      for (@keywords) { next unless $line =~ /$_/i; push @found, $_; }

      I think it's a bit clearer and more obvious what's going on. Nothing earth-shattering, but a lot of these kind of things can add up.

      Update: then again, I might even go sideways on it:

      my @found = grep { $line =~ /$_/i } @keywords;
        Me and the ternary operator have a special relationship actually, i suppose it shows. Now that i take a more calm look at it, i'll take it one step further. I think the most elegant of all would actually be:
        foreach (@keywords) { push @found, $_ if $line =~ m/$_/i; }

        next is not really useful, and dare i say obsolete, since there is no other code aside the regexp conditional in the foreach block. As for the grep rewrite, there is a gotcha, which might complicate things in certain situations. But i'll save it for another day since it isn't relevant to this thread. But if anyone is interested take a look here.

      That example does not produce an error.
      $ cat psychotic.pl my @found; my $line = 'Alpha and some junk here'; my @keywords = qw(alpha beta gamma); foreach (@keywords) { $line =~ m/$_/i ? push @found, $_ : next } foreach (@found) { print } $ perl psychotic.pl ; echo alpha
Re: Missing $ on loop variable
by robin (Chaplain) on Dec 02, 2005 at 22:55 UTC
    I guess this must be a bug in that particular sub-version of perl. I don't have a copy of 5.6.1 handy to test it on, and it's even possible that Sun shipped a non-standard version.

    Does anyone else remember why there's a special error message for missing $ on loop variable, rather than it just being a generic syntax error?

    Update: My memory is faulty.
      There is a comment in the other thread Missing $ on loop variable? about how shell programmers might forget that in Perl the "$" is required.
        That's an interesting idea. Perhaps that's it after all.

        I might be mis-remembering: perhaps it was the @ on the array that was optional? I'm pretty sure it was one of them, but it's been a long time since I've had Perl 4 on my computer.Update It is neither. I must have been thinking of what japhy says.