[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]

Re: Overly magical range operator



On Wed, 15 Dec 1999 10:29:36 PST, Tom Phoenix wrote:
>According to perlop:
>
>    The range operator (in a list context) makes use of the magical
>    auto-increment algorithm if the operands are strings.
>
>Despite this intention, it seems that only the left operand needs to be a
>string.
>
>    $ perl -wle '$count = () = "0"..-1; print $count'
>    100
>
>Here's a patch. I hope that someone who understands the guts will verify
>that this is doing what I think it's doing! Also, this is just a start to
>the patch; I couldn't see how to fix C<for ("0"..-1) {....}> to do the
>same. :-(

This probably merits close attention from the compatibility police.


Sarathy
gsar@ActiveState.com
-----------------------------------8<-----------------------------------
Change 4730 by gsar@auger on 1999/12/28 19:55:56

	range operator does magical string increment iff both operands
	are non-numbers, from Tom Phoenix <rootbeer@redcat.com>; fixed
	the "foreach (RANGE)" case as well

Affected files ...

... //depot/perl/pp_ctl.c#172 edit
... //depot/perl/t/op/range.t#8 edit

Differences ...

==== //depot/perl/pp_ctl.c#172 (text) ====
Index: perl/pp_ctl.c
--- perl/pp_ctl.c.~1~	Wed Jan  5 11:32:48 2000
+++ perl/pp_ctl.c	Wed Jan  5 11:32:48 2000
@@ -997,7 +997,9 @@
 	    mg_get(right);
 
 	if (SvNIOKp(left) || !SvPOKp(left) ||
-	  (looks_like_number(left) && *SvPVX(left) != '0') )
+	    SvNIOKp(right) || !SvPOKp(right) ||
+	    (looks_like_number(left) && *SvPVX(left) != '0' &&
+	     looks_like_number(right) && *SvPVX(right) != '0'))
 	{
 	    if (SvNV(left) < IV_MIN || SvNV(right) > IV_MAX)
 		DIE(aTHX_ "Range iterator outside integer range");
@@ -1674,7 +1676,11 @@
 	if (SvTYPE(cx->blk_loop.iterary) != SVt_PVAV) {
 	    dPOPss;
 	    if (SvNIOKp(sv) || !SvPOKp(sv) ||
-		(looks_like_number(sv) && *SvPVX(sv) != '0')) {
+		SvNIOKp(cx->blk_loop.iterary) || !SvPOKp(cx->blk_loop.iterary) ||
+		(looks_like_number(sv) && *SvPVX(sv) != '0' &&
+		 looks_like_number((SV*)cx->blk_loop.iterary) &&
+		 *SvPVX(cx->blk_loop.iterary) != '0'))
+	    {
 		 if (SvNV(sv) < IV_MIN ||
 		     SvNV((SV*)cx->blk_loop.iterary) >= IV_MAX)
 		     DIE(aTHX_ "Range iterator outside integer range");

==== //depot/perl/t/op/range.t#8 (xtext) ====
Index: perl/t/op/range.t
--- perl/t/op/range.t.~1~	Wed Jan  5 11:32:48 2000
+++ perl/t/op/range.t	Wed Jan  5 11:32:48 2000
@@ -1,6 +1,6 @@
 #!./perl
 
-print "1..13\n";
+print "1..15\n";
 
 print join(':',1..5) eq '1:2:3:4:5' ? "ok 1\n" : "not ok 1\n";
 
@@ -64,3 +64,12 @@
     $bad = 1 unless $x eq 'a:b:c:d:e';
     print $bad ? "not ok 13\n" : "ok 13\n";
 }
+
+# Should use magical autoinc only when both are strings
+print "not " unless 0 == (() = "0"..-1);
+print "ok 14\n";
+
+for my $x ("0"..-1) {
+    print "not ";
+}
+print "ok 15\n";
End of Patch.


[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index][Thread Index][Top&Search][Original]