in reply to Two Range Operator Anomalies

For the first question, read further. "The range operator (in list context) makes use of the magical auto-increment algorithm if the operands are strings."

For the second question, you got bitten by the side-effect of an optimisation. Constant ranges are expanded into a list at compile-time. You modified this list, affecting future use of it. Workaround:

for ('a'..'f') { my $letter = $_; # Make modifiable copy ... }

Update: Misunderstood the first question

Replies are listed 'Best First'.
Re^2: Two Range Operator Anomalies
by liverpole (Monsignor) on Mar 11, 2009 at 16:25 UTC
    Thanks, ikegami.

    The documentation "The range operator (in list context) makes use of the magical auto-increment algorithm if the operands are strings." didn't quite shed any light on it, as I'm already familiar with the magical auto-increment feature.  (But I think hbm got it below, which clarified something that the documenation could possibly use better wording for).

    As to the second, however, you say the workaround is to use a "modifiable copy":

    for ('a'..'f') { my $letter = $_; # Make modifiable copy ... }

    But why isn't the my that I'm using here:

    foreach my $letter ('a' ... 'c', 'd' ... 'f') { print " $letter"; $letter = uc $letter; }

    doing exactly that??

    Update:  Actually, I see why. Of course, because it's assigning to a modifiable lvalue of the variable. Never mind.

    But I'm still curious why this:

    #!/usr/bin/perl -w use strict; use warnings; sub letters { foreach my $letter ('a' ... 'c') { print " $letter"; $letter = uc $letter; } print "\n"; } letters(); letters(); letters();

    Doesn't exhibit the same behavior? Is it simply that it doesn't undergo the same optimization step you referred to?


    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/

      The documentation [...] didn't quite shed any light on it,

      I thought misunderstood the question and have already struck out that part of my post while you were composing your reply.

      But why isn't the my that I'm using here doing exactly that??

      For loop iterators are aliases for efficiency and to allow you to modify the list.

      for my $s (@strings) { $s = trim($s); }

      But I'm still curious why [foreach my $letter ('a' ... 'c')] Doesn't exhibit the same behavior?

      There's no range operator in that statement. for (X .. Y) is a counting loop. It doesn't flatten X .. Y. See Re: For vs. Foreach