in reply to Odd behaviour with $. and <DATA>

Works fine here:

$ cat x.pl #!/usr/bin/perl -w use strict; # Test to see if $. really does break when reading from DATA. { #foreach (<DATA>) { print "Try line $.:$_"; } while(<DATA>) { print "Try line $.:$_"; } } __DATA__ This is line 1. This is the second line. Here is line 3. The last line is line 4.$ perl ./x.pl Try line 1:This is line 1. Try line 2:This is the second line. Try line 3:Here is line 3. Try line 4:The last line is line 4.$
Note how I removed the foreach and replaced with while. The foreach will slurp the file in (<DATA> in list context) and then loop through the list. while, however, is evaluating in scalar context, which means read one line, deal with it, move to the next line.

Replies are listed 'Best First'.
Re^2: Odd behaviour with $. and <DATA>
by talexb (Chancellor) on Jan 16, 2006 at 20:35 UTC

    OK -- so the difference is how foreach and while operate differently. Thanks -- that explains it all.

    But (since I'm not allowed to use the phrase beg the question) I wonder why that is .. foreach suggests that, for each element in the list, it's going to do something. It doesn't suggest that it's going to slurp up the entire list at once.

    Update Sorry, disregard this .. you've explained that one works in list context and the other works in scalar context .. my question is reduced to 'Why do they work in different contexts' and I guess the answer is, 'They do -- period'.

    Update2 This is properly explained on p.34 (the first paragraph) of the Camel (3rd edition) -- if and while work in scalar context, and foreach works in list context.

    Alex / talexb / Toronto

    "Groklaw is the open-source mentality applied to legal research" ~ Linus Torvalds

      Before foreach can iterate over the list, it needs to be built. It works the same way for function. A list must be built before it can be used. In this case, building the list means reading the entire file.

      foreach (x..y) is an exception to this. That list is evaluated lazily.

      But (since I'm not allowed to use the phrase beg the question) I wonder why that is .. foreach suggests that, for each element in the list, it's going to do something. It doesn't suggest that it's going to slurp up the entire list at once.

      Indeed: but before iterationg over the list, the latter has to be created, which should answer your question. Said, this, the list has to be created unless we have "lazy evaluation", which we curretly have not, with the exception of a pair of special cases, whereas Perl 6 will have it by default -and you'll generally need to explicitly tell it to do differently, if you want so!- in fact for will be the default for iterating over iterators, be them regular lists, filehandles or more exotic objects.