in reply to Syntax error - "my" within foreach loop

What's wrong? I found out, if you define %count outside the foreach loop with my %count; and omit "my" within the loop, it's working. But "my" within the loop results in the mentioned warning.
Nothing! That's exactly how you do it
#!/usr/bin/perl use warnings; use strict; chomp(my @words = <STDIN>); my %count; foreach my $word (@words) { $count{$word} += 1; } foreach my $key (sort keys %count) { print "$key was found $count{$key} times\n"; }

Replies are listed 'Best First'.
Re^2: Syntax error - "my" within foreach loop
by Klammer (Acolyte) on Apr 13, 2008 at 19:30 UTC
    Thanks FunkyMonk. As far as I understand it, it's just wrong to use "my" within the foreach loop in this context.
      It's not wrong because it's in a loop, but because you're accessing a hash element.

      my declares a new, lexical variable. But you don't want to declare a new variable, you're accessing an item in an existing data structure.

        OK, I see. But if I don't declare %count with my %count% the hash isn't an existing data structure, isn't it? Do I always have to declare a hash prior to using it within the foreach loop, or is there a way to do it all in one step within the loop? Sorry if this sounds stupid. ;)

      I believe the point of "my" declarations is to simplify finding the "root" of a scoped variable. Variable scoping is an effect of command nesting; in your example the "$count{$word}" declaration is nested in the first foreach loop, which is within the scope of the "my $word" declaration and the "my %count" declaration (necessarily added by FunkyMonk). The variables have this scope because they are outside the loop. That means the variables are also available to the next foreach loop. Since the only one used is %count, you could write: foreach (@words) { my $word = $_; and the scope of $word would be limited to the nest where it is actually used.

      Unfortunately, niether your nor FunkyMonk's code actually works properly because of "@words=<STDIN>". I am sure what you wanted to do was this:

      #!/usr/bin/perl use warnings; use strict; chomp(my $input = <STDIN>); my @words = split / /,$input; my %count; foreach my $word (@words) { $count{$word} += 1; } foreach my $key (sort keys %count) { print "$key was found $count{$key} times\n"; }
      Scoping and the purpose of the "my" declaration will become much clearer when you are writing longer, more complicated and more heavily nested scripts with subroutines, etc. Do stick with "use strict"
      Actually, what it seems like to me is, your original code was trying to access an hash that hadn't been created, so it, the perl interpreter, may have thought it was a scalar with a set of braces at the end of it. Just a thought. Anyone else have an idea?