Larry wrote:

» Indeed, that preference is why Perl 6 can (we hope) get away with
» autochomping, where Perl 5 can't (as easily).  Or more accurately,
» we choose not to special-case "while (<>)" as Perl 5 does (because
» even Perl 5 has difficulties with files that are accidentally
» "autochomped" by omitting the final newline in the file).

I don't understand what you mean, Larry.

Sure, Perl *4* had such difficulties, since having only 
chop(), not an RS-aware chomp(), you'd get a:

    substr($line,-1) = q() 

whether you "needed" it or not (although it returns the old LHS not the 
new RHS).  It's not conditional, except that it won't give you negatively
lengthed null lines.  And so those folks who deemed textfiles as
\n-SEPARATED sequences of lines, not \n-TERMINATED sequences, would
therefore shorten their files by a character if they didn't check first.

But with Perl *5*, since chomp() is RS-aware in that it instead 
looks for it leaps--er, checks before it chomps--so I'm don't 
at all understand what you mean when you say

» even Perl 5 has difficulties with files that are accidentally
» "autochomped" by omitting the final newline in the file).

I don't see where you see Perl 5 having that problem.  This 
seems safe enough, which to a first approximation about this:

    $line =~ s[ ${RS} \z ][]x;

Even when $RS = q!!, making for squishy record terminators
for both readline() and also for chomp(), I see no destructive 
action.  Often enough I set $RS = "%%\n", and sometimes I remember
to put a %% at the end, and sometimes I don't, but no harm done.

The only place I can see there being a "problem" is with 
something like 

    % perl -i'IBACKUP/*' lpe 's/foo/bar/g' file*

and some of those files start out without their terminator.

Here though the problem is opposite what you mention, in 
that once Perl's had its way with them, all files are 
canonically terminated whether they began that way or not.

» But we're trying very hard to get rid of most such special
» cases in Perl 6.  Usually we can get the recommended Perl
» 6 code to just DWYM as a fallout of the general semantics,
» but in this particular case, if you really want to read
» your input with while, there's a slight "regression" from
» Perl 5 insofar as you must explicitly use defined(). This
» de-huffmanization is intended as a subtle encouragement to
» move from Item-Think towards List-Think.  :)

Oh. 

You mean like for directories containing a file whose 
name is the 1-char string, "0", and that file pre-emptively
terminating a readdir loop the way it used to.  

Whereas nowadays, our compassionate compiler, spotting an
incorrectly tested assignment governing a while's conditional:

    while ( $thingie = <read{dir,lin[ke]}>() )  { ;;; } 

graciously inserts a defined() opcode for you.

Wasn't the reasoning that whenever there's something each and every
program must without fail do if it's to be a correct program, that
something is too important to be left up to the programmer to forget?

Is this rationale no longer sound?  

It still makes sense to me.

Then again, folks can still confuse interating using a while with 
iterating using foreach.  They often appear act the same, so 
the wrong mental model is held.  People 
grow complacent, having seen the misleading apparent interchangeability
between

    while ( $src = <*.[Cchy]> )  { }
    foreach $src ( <*.[Cchy]> )  { }

or

    while ( $datum = <$yafh> )   { }
    foreach $datum ( <$yafh> )   { }

They then get quite hung up when these aren't the same:

    foreach $item (@someitems) { ;;; }
    while ( $item = shift(@someitems) ) { ;;; } 

I guess removing special awareness for <read{dir,lin[ke]}> might
prod them into thinking more about the whole thing. After all,
no special blessing of an inserted defined() op can save them
here, condering that this:

    while ( defined( $item = shift(@someitems) ) ) { ;;; } 

still isn't the same as this:

    while (@someitems) { 
        $item = shift(@someitems);
        ;;;
    }

Still, whenever there's something everyone has to do for a program
to function correctly, shouldn't Perl be doing it for them whenever
possible, lest they sometimes forget?  Think of the Python programs
that die because they forget to pre-extend their lists to grow it
by one.  Perl after all never makes you write:

    if ($#someitems < $index) {
        $#someitems = $index;
    } 
    $sometimes[$index] = $value;

EACH AND EVERY $...@%&* time you want to write

    $sometimes[$index] = $value;

but Python does. 

But perhaps this is something for the <ITERATOR> to 
see to tkaing care of, or the I/O aka line-discipline, 
or whatever model you prefer.

--tom

Reply via email to