Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Series of letters doesn't stop at end point #1754

Closed
p6rt opened this issue May 8, 2010 · 7 comments
Closed

Series of letters doesn't stop at end point #1754

p6rt opened this issue May 8, 2010 · 7 comments

Comments

@p6rt
Copy link

p6rt commented May 8, 2010

Migrated from rt.perl.org#74990 (status was 'resolved')

Searchable as RT74990$

@p6rt
Copy link
Author

p6rt commented May 8, 2010

From @moritz

21​:34 <@​moritz_> rakudo​: say 'a'...'z'
21​:34 <+p6eval> rakudo ab2322​:
21​:34 <+p6eval>
..OUTPUT«abcdefghijklmnopqrstuvwxyzaaabacadaeafagahaiajakalamanaoapaqarasatauavawaxayazbabbbcbdbebfbgbhbibjbkblbmbnbobpbqbrbsbtbubvbwbxbybzcacbc
ccdcecfcgchcicjckclcmcncocpcqcrcsctcucvcwcxcyczdadbdcdddedfdgdhdidjdkdldmdndodpdqdrdsdtdudvdwdxdydzeaebecedeeefegeheiejekelemeneoepeqereseteuevewex…

Should only go up to z.

Moritz

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From @kyleha

This is an automatically generated mail to inform you that tests are now available in t/spec/S03-operators/series-simple.t

commit b3d941a4f9a902c1b2fa7619dd68f832a2fbb802
Author​: mmcleric <mmcleric@​c213334d-75ef-0310-aa23-eaa082d1ae64>
Date​: Sat Jun 12 15​:53​:47 2010 +0000

  test for RT#​74990
 
  git-svn-id​: http://svn.pugscode.org/pugs@&#8203;31218 c213334d-75ef-0310-aa23-eaa082d1ae64

Inline Patch
diff --git a/t/spec/S03-operators/series-simple.t b/t/spec/S03-operators/series-simple.t
index 5c74ad4..46653ba 100644
--- a/t/spec/S03-operators/series-simple.t
+++ b/t/spec/S03-operators/series-simple.t
@@ -73,4 +73,8 @@ is ('c', { $_ } ... *).batch(10).join(', '), 'c, c, c, c, c, c, c, c, c, c', 'se
 is ('c', 'c' ... *).batch(10).join(', '), 'c, c, c, c, c, c, c, c, c, c', 'series started with two identical letters';
 is ('c', 'c', 'c' ... *).batch(10).join(', '), 'c, c, c, c, c, c, c, c, c, c', 'series started with three identical letters';
 
-done_testing;
\ No newline at end of file \+\# tests for alphabetical series crossing 'z' \+\#?rakudo 1 todo "RT#​74990​: Series of letters doesn't stop at end point" \+is \('x' \.\.\. 'z'\)\.join\(', '\), 'x, y, z', "series ending with 'z' don't cross to two\-letter strings"; \+ \+done\_testing;

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From justin.sahs@gmail.com

The problem was that 'z' cmp 'aa' = 1, because cmp is lexicographic
order, whereas in character sequences, we want to first order by length,
then lexicographic.

Patch attached. NOTE​: THIS PATCH ASSUMES MY PATCH FROM #​75674 HAS
ALREADY BEEN APPLIED.

@p6rt
Copy link
Author

p6rt commented Jun 12, 2010

From justin.sahs@gmail.com

74990.patch
diff --git a/src/core/operators.pm b/src/core/operators.pm
index c09e752..5c6c220 100644
--- a/src/core/operators.pm
+++ b/src/core/operators.pm
@@ -313,6 +313,17 @@ class Whatever { ... }
 # the magic one that handles stuff like
 # 'a' ... 'z' and 'z' ... 'a'
 our multi sub infix:<...>($lhs, $rhs) {
+	# in character sequences e.g. 'a' ... 'z', strings
+	# are not compared in their normal lexicographic 
+	# order; in particular, shorter strings are always
+	# before longer strings, e.g. 'z' < 'aa'.
+	my multi sub infix:<ccmp>(Str $a, Str $b) {
+		$a.chars cmp $b.chars || $a cmp $b;
+	}
+	my multi sub infix:<ccmp>($a, $b) {
+		$a cmp $b;
+	}
+
     if $rhs ~~ Whatever {
         my $i = $lhs;
         return gather {
@@ -325,22 +336,22 @@ our multi sub infix:<...>($lhs, $rhs) {
 
     gather {
         take $lhs;
-        if ($lhs cmp $rhs) == 1 {
+        if ($lhs ccmp $rhs) == 1 {
             my $x = $lhs;
             # since my $a = 'a'; $a-- gives
             # "Decrement out of range" we can't easily
             # decrement over our target, which is why the
             # case of going backwards is slighly more complicated
             # than going forward
-            while (--$x cmp $rhs) == 1 {
+            while (--$x ccmp $rhs) == 1 {
                 # need to make a fresh copy here because of RT #62178
                 my $y = $x;
                 take $y;
             }
-            take $x if ($x cmp $rhs) == 0;
-        } elsif ($lhs cmp $rhs) == -1 {
+            take $x if ($x ccmp $rhs) == 0;
+        } elsif ($lhs ccmp $rhs) == -1 {
             my $x = $lhs;
-            while (++$x cmp $rhs) <= 0 {
+            while (++$x ccmp $rhs) <= 0 {
                 my $y = $x;
                 take $y;
             }
@@ -351,7 +362,7 @@ our multi sub infix:<...>($lhs, $rhs) {
 			# 1 cmp 1,2,3 == -1, rather than 0,
 			# so if $lhs cmp $rhs == -1, the first element
 			# of @rest has already been taken
-			@rest.shift if $lhs cmp $rhs == -1;
+			@rest.shift if $lhs ccmp $rhs == -1;
             for @rest {
                 take $_;
             }
@@ -414,8 +425,19 @@ our multi sub infix:<...>(Code $lhs, $rhs) {
 }
 
 our multi sub infix:<...>(@lhs is copy, $rhs) {
+	# in character sequences e.g. 'a' ... 'z', strings
+	# are not compared in their normal lexicographic 
+	# order; in particular, shorter strings are always
+	# before longer strings, e.g. 'z' < 'aa'.
+	my multi sub infix:<ccmp>(Str $a, Str $b) {
+		$a.chars cmp $b.chars || $a cmp $b;
+	}
+	my multi sub infix:<ccmp>($a, $b) {
+		$a cmp $b;
+	}
+
     my sub succ-or-pred($lhs, $rhs) {
-        if $rhs ~~ Whatever || $lhs cmp $rhs != 1 {
+        if $rhs ~~ Whatever || $lhs ccmp $rhs != 1 {
             -> $x { $x.succ };
         } else {
             -> $x { $x.pred };
@@ -423,7 +445,7 @@ our multi sub infix:<...>(@lhs is copy, $rhs) {
     }
 
     my sub succ-or-pred2($lhs0, $lhs1, $rhs) {
-        if $lhs1 cmp $lhs0 == 0 {
+        if $lhs1 ccmp $lhs0 == 0 {
             $next = { $_ };
         } else {
             $next = succ-or-pred($lhs1, $rhs);
@@ -477,15 +499,15 @@ our multi sub infix:<...>(@lhs is copy, $rhs) {
             @args.push($v) if $i >= @lhs.elems - $top;
         }
 
-        if !$limit.defined || $limit cmp $j != 0 {
+        if !$limit.defined || $limit ccmp $j != 0 {
             loop {
                 my $i = $next.(|@args);
                 my $j = $i;
 
                 my $cur_cmp = 1;
                 if $limit.defined {
-                    $cur_cmp = $limit cmp $j;
-                    last if (@args[@args.elems - 1] cmp $limit) == $cur_cmp;
+                    $cur_cmp = $limit ccmp $j;
+                    last if (@args[@args.elems - 1] ccmp $limit) == $cur_cmp;
                 }
                 take $j;
                 last if $cur_cmp == 0;

@p6rt
Copy link
Author

p6rt commented Dec 10, 2010

From @thundergnat

This is Rakudo Perl 6, version 2010.11 built on parrot 2.10.1
RELEASE_2_10_1-679-g9bec614

perl6 -e "say 'a'...'z'"
abcdefghijklmnopqrstuvwxyz

Works ok locally should be closable if tests have been added to roast.

@p6rt
Copy link
Author

p6rt commented Oct 1, 2011

@moritz - Status changed from 'open' to 'resolved'

@p6rt p6rt closed this as completed Oct 1, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant