5

I'm learning Perl with the Llama, 6th ed., and some of the programs in the first chapters don't work with "use 5.014", and I'm not sure why. For example:

#!/usr/bin/perl

#use 5.014;

$n = 1;
while ($n < 10) {
        $sum += $n;
        $n += 2;
}
print "The total was $sum.\n";

This works with "use 5.014" commented out, but with it included, I get these errors:

Global symbol "$n" requires explicit package name at ch3loop.pl line 5.
Global symbol "$n" requires explicit package name at ch3loop.pl line 6.
Global symbol "$sum" requires explicit package name at ch3loop.pl line 7.
Global symbol "$n" requires explicit package name at ch3loop.pl line 7.
Global symbol "$n" requires explicit package name at ch3loop.pl line 8.
Global symbol "$sum" requires explicit package name at ch3loop.pl line 10.
Execution of ch3loop.pl aborted due to compilation errors.

However, if I put "my" before the first instances of the variables, it still doesn't run, but for a different reason:

Global symbol "$sum" requires explicit package name at ch3loop.pl line 10.
Execution of ch3loop.pl aborted due to compilation errors.

Can someone explain what's going on? I know I can just run this without "use 5.014", but it does say on the cover of the book that the 6th ed. "covers Perl 5.14", so I'm puzzled.

Thanks.

Marc Adler
  • 534
  • 1
  • 4
  • 16
  • 1
    This errors will show up with every perl version starting with 5.11 if you `use 5.0xx`. With this version the `strict` pragma is [enabled implicitly](http://search.cpan.org/~rjbs/perl-5.16.0/pod/perl5120delta.pod#Implicit_strictures) except for one liners. – matthias krull Aug 04 '12 at 07:03
  • See also [Why are use warnings; use strict; not default in Perl?](http://stackoverflow.com/questions/6050031/why-are-use-warnings-use-strict-not-default-in-perl) and [What exact features does 'use 5.014' enable?](http://stackoverflow.com/a/6410837/367180) – matthias krull Aug 04 '12 at 07:10

3 Answers3

13

Since v5.12, when you say use VERSION with nothing else, it automatically turns on strict. Since we don't cover the ways around your particular problem until the "Subroutines" chapter, we don't do anything in the previous chapters that require you to do that.

Learning Perl is designed as a tutorial, so we expect that you won't do anything in a program until we've explicitly shown it to you. That way, we don't have to explain all of Perl in the first chapter.

I tend to not use any version declaration until I use a feature that requires it, and we don't do that in the beginning chapters.

Good luck with the rest of the book. :)

brian d foy
  • 129,424
  • 31
  • 207
  • 592
  • 5
    @Mark - and in case you may have missed it, in the interests of total transparency, match up the name of the user who answered this with the author list on the cover of "Learning Perl" :) – DVK Aug 04 '12 at 13:00
  • That's a great explanation. Will do. Thanks! – Marc Adler Aug 05 '12 at 08:40
  • Wow, he's one of the guys who wrote the book! Straight from the llama's mouth, as it were. :) – Marc Adler Aug 05 '12 at 14:53
5

I guess that after that version it automatically enables use strict mode, which forces you declare the scope of each variable. (this is generally a good thing, and it makes you much less likely to make hard to spot mistakes).

You're likely getting the $sum error because I'm guessing you put my $sum inside the while loop, so it is out of scope in the final print statement.

You want to set my $sum = 0; right before and outside the while loop, so that it maintains scope outside of the while loop. If you declare sum inside the while loop, the value will expire and be reset after each iteration of the loop, and it will not exist when you try to print it.

Tim
  • 35,413
  • 11
  • 95
  • 121
  • Hmm, you mean like this? #!/usr/bin/perl use 5.014; my $sum = 0; my $n = 1; while ($n < 10) { my $sum += $n; $n += 2; } my $sum = 0; print "The total was $sum.\n"; I assumed it would just return "The total was 0." at the end, and it did. I must have misunderstood what you meant. – Marc Adler Aug 04 '12 at 02:57
  • @MarcAdler Comments don't support advanced formatting. Anyway, you don't want to keep declaring 'my' in multiple places for the same variable. Just declare `my $sum` at the top of the program, and then just use it like normal after that. You need to read up about **variable scope** to understand what **my** means. – Tim Aug 04 '12 at 04:57
  • @MarcAdler - the only formatting possible in comments to help with code is backticks (like `my $sum` in Tim's comment) for fixed width text. Full rules for Markdown subset that comments support can be found on [Meta Stack Overflow](http://meta.stackexchange.com/questions/2115/text-formatting-now-allowed-in-comments-list-of-proven-and-disproven-abilities) or by clicking the little "help" link to the right of the comment adding textbox – DVK Aug 04 '12 at 12:59
2

use <version>; enables strict by default. So declare the variables like below-

#!/usr/bin/perl
use 5.014;
my $sum;
my $n=1;

while ($n < 10) {
        $sum += $n;
        $n += 2;
}
print "The total was $sum.\n";
Anjan Biswas
  • 7,746
  • 5
  • 47
  • 77
  • This answer doesn't explain what's happening. You also commented out `use 5.014`; which is the cause of the OP's confusion. – friedo Aug 04 '12 at 10:17