From: "Berger, Daniel" Date: 2007-01-10T06:00:06+09:00 Subject: Re: String#upto edge case - empty string causes infinite loop > -----Original Message----- > From: Arnaud Bergeron [mailto:abergeron@gmail.com] > Sent: Tuesday, January 09, 2007 1:36 PM > To: ruby-core@ruby-lang.org > Subject: Re: String#upto edge case - empty string causes infinite loop > > > On 1/8/07, Berger, Daniel wrote: > > > -----Original Message----- > > > From: Arnaud Bergeron [mailto:abergeron@gmail.com] > > > Sent: Monday, January 08, 2007 12:49 PM > > > To: ruby-core@ruby-lang.org > > > Subject: Re: String#upto edge case - empty string causes infinite > > > loop > > > > > > > > > Since "\377".succ yields "\001\000" I belive it would make more > > > sense having "".succ return "\000" and continue on from there. > > > > Hm, it does seem to be a tradition among other languages: > > These examples are not exactly the same situation, as none of > these languages have the equivalent of succ for strings. > > > # Perl > > my $str = ""; > > print ++$str; # 1 > > Perl is the only language I'm not familiar with here, so I am > not really sure what happens here but I heard about automagic > conversion of string to numbers. > > > /* C */ > > #include > > > > int main(){ > > char* empty = ""; > > printf("Value: %i\n", atoi(empty) + 1); /* 1 */ > > return 0; > > } > > Here you are explicitly converting the string to a number > (and due to stupidity, atoi interprets "" as being the number > 0). After adding 1 it is no suprise that it prints 1. Well, I guess my point was that atoi("") returns 0, stupid or not. > > /* Java */ > > public class EmptyTest{ > > public static void main(String[] args){ > > String empty = ""; > > System.out.println(empty + 1); /* 1 */ > > } > > } > > Here you get string concatenation. You could have written "" > + "1" and it would have only been more explicit. The number > 1 gets converted to a string and if you concatenate that > string with the empty string you get "1". Oops, right. > The .succ function is a different beast than these examples > because it returns the next string in order. > > > > However there might be a problem because letters are treated > > > differently. "z".succ yield "aa" and not "}" and the > same is true > > > for "Z" so this might need more thought, but in my > opinion yielding > > > the empty string once is the last expected behavior. > > > > As you suggest, I'm not sure what repurcussions changing the return > > value of "".succ might have. My approach at least has the > advantage > > of being safe in that regard. However, I can live with either > > approach. It is just an edge case after all. :) > > I would have it return "\000" because "" < "\000" and is the > lowest value for a string for which this inegality is true. > Having "".succ return "" breaks the implicit assuption that > foo < foo.succ. > > irb(main):001:0> a = 1 > => 1 > irb(main):002:0> a < a.succ > => true > irb(main):003:0> a = "" > => "" > irb(main):004:0> a < a.succ > => false I understand your point, but I could just as well argue that there is no logical successor to an empty string, and therefore it's a special case. Another point to consider is that, if we have "".succ return "0", we get this result from String#upto: "".upto(2) => ["", "0", "1", "2"] Either approach feels more or less arbitrary. I vote to err on the side of caution and stick with my original patch. :) Regards, Dan This communication is the property of Qwest and may contain confidential or privileged information. Unauthorized use of this communication is strictly prohibited and may be unlawful. If you have received this communication in error, please immediately notify the sender by reply e-mail and destroy all copies of the communication and any attachments.