![]() |
Ascii characters in a loop
The following loop works fine in Perl:
for ($l = 'a'; $l le 'y'; $l++) { print "$l"; } However, if I try to loop from a through to z, the loop does not work: for ($l = 'a'; $l le 'z'; $l++) { print "$l"; } I know that a for each loop would work, but that is not what I want. Regards, Mark. -- Mark Hobley 393 Quinton Road West QUINTON Birmingham B32 1QE Telephone: (0121) 247 1596 International: 0044 121 247 1596 Email: markhobley at hotpop dot donottypethisbit com http://markhobley.yi.org/ |
Re: Ascii characters in a loop
Mark Hobley wrote:
> The following loop works fine in Perl: > > for ($l = 'a'; $l le 'y'; $l++) { > print "$l"; > } > > However, if I try to loop from a through to z, the loop does not work: It does but it produces results you might not have expected. > > for ($l = 'a'; $l le 'z'; $l++) { > print "$l"; > } > Because of the way the post-increment operator works on strings. See `perldoc perlop` under Auto-increment. The value after 'z' is 'aa' and 'aa' is still stringwise less than 'z'. Luckily 'zz' is greater than 'z'. |
Re: Ascii characters in a loop
RedGrittyBrick wrote:
> Mark Hobley wrote: >> The following loop works fine in Perl: >> >> for ($l = 'a'; $l le 'y'; $l++) { >> print "$l"; >> } >> >> However, if I try to loop from a through to z, the loop does not work: > > It does but it produces results you might not have expected. > >> >> for ($l = 'a'; $l le 'z'; $l++) { >> print "$l"; >> } >> > > Because of the way the post-increment operator works on strings. > See `perldoc perlop` under Auto-increment. > > The value after 'z' is 'aa' and 'aa' is still stringwise less than 'z'. > > Luckily 'zz' is greater than 'z'. Oh yes, Why exactly don't you want a foreach loop? C:\>perl -e "for $x ('a'..'z') { print \"$x,\";}" a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y, z, C:\>perl -e "$e='z'; for $x ('a'..$e) { print \"$x,\";}" a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y, z, |
Re: Ascii characters in a loop
On 1/13/07 16:04, in article rm4o74-cqk.ln1@neptune.markhobley.yi.org, "Mark
Hobley" <markhobley@hotpop.deletethisbit.com> wrote: > The following loop works fine in Perl: > > for ($l = 'a'; $l le 'y'; $l++) { > print "$l"; > } > > However, if I try to loop from a through to z, the loop does not work: > > for ($l = 'a'; $l le 'z'; $l++) { > print "$l"; > } > > I know that a for each loop would work, but that is not what I want. > I think you're expecting: abcdefghijklmnopqrstuvwxyz And if that's what you want, you must use ne instead of le to end the loop. for ($l = 'a'; $l ne 'z'; $l++) { print "$l"; } If you replace print "$l"; with print "$l "; you can see what's happening. Change the comparison from le the ne, and the loop stops at z, but with le, the loop does not stop until zz is less than z. Try this little experiment. print join(' ', sort qw( a b c x y z aa bb cc xx yy zz )), "\n"; There are two things happening in your second loop. First, Auto-increment for string data is smarter than you expect, maybe too smart. The next value after z is aa. Second, operators like lt, le, eq, ne, ge, and gt are stringwise comparisons. This means the result of a comparison reflects the sorting order of the strings, and as you see from the experiment, aa is less than z. -- Regards, Mark |
Re: Ascii characters in a loop
Mark Donovan <novafyre@hotmail.com> wrote:
> On 1/13/07 16:04, in article rm4o74-cqk.ln1@neptune.markhobley.yi.org, > "Mark Hobley" <markhobley@hotpop.deletethisbit.com> wrote: [..] >> for ($l = 'a'; $l le 'z'; $l++) { >> print "$l"; >> } >> >> I know that a for each loop would work, but that is not what I want. >> > > I think you're expecting: abcdefghijklmnopqrstuvwxyz > > And if that's what you want, you must use ne instead of le to end the > loop. No, 'aa' Which might confuse a lot of people. > for ($l = 'a'; $l ne 'z'; $l++) { > print "$l"; > } abcdefghijklmnopqrstuvwxy for ($l = 'a'; $l ne 'aa'; $l++) { print "$l"; } abcdefghijklmnopqrstuvwxyz > If you replace > print "$l"; > with > print "$l "; > you can see what's happening. Change the comparison from le the ne, > and the loop stops at z, but doesn't reach the print ;-) -- John Experienced Perl programmer: http://castleamber.com/ Perl help, tutorials, and examples: http://johnbokma.com/perl/ |
Re: Ascii characters in a loop
RedGrittyBrick <RedGrittyBrick@SpamWeary.foo> wrote:
> Oh yes, > > Why exactly don't you want a foreach loop? My guess: because he wants to know why this one "doesn't work" instead of reading: "use this instead". To me it was educational (as in if someone has asked to write that loop like that I am sure it would have bitten me as well), so thanks OP :-) -- John Experienced Perl programmer: http://castleamber.com/ Perl help, tutorials, and examples: http://johnbokma.com/perl/ |
Re: Ascii characters in a loop
John Bokma <john@castleamber.com> wrote:
> > My guess: because he wants to know why this one "doesn't work" instead of > reading: "use this instead". I am writing Perl documentation. All these points seem to be missed in the reference books that I am using, which incidently are extremely big and run into several thousand pages each and cost me quite a few quid. It seems strange that if I increment $l (which equals 'z') then I now have a value that is comparitively less than 'z'. This looks like a bug to me, at least in the context of an a to z loop. Regards, Mark. -- Mark Hobley 393 Quinton Road West QUINTON Birmingham B32 1QE Telephone: (0121) 247 1596 International: 0044 121 247 1596 Email: markhobley at hotpop dot donottypethisbit com http://markhobley.yi.org/ |
Re: Ascii characters in a loop
Mark Hobley schreef:
> The following loop works fine in Perl: > > for ($l = 'a'; $l le 'y'; $l++) { > print "$l"; > } > > However, if I try to loop from a through to z, the loop does not work: > > for ($l = 'a'; $l le 'z'; $l++) { > print "$l"; > } It does work, but not in the way that you suspect(ed). See also perldoc -q quoting. > I know that a for each loop would work, but that is not what I want. Better mention what you do want. -- Affijn, Ruud "Gewoon is een tijger." |
Re: Ascii characters in a loop
Mark Hobley wrote:
> John Bokma <john@castleamber.com> wrote: >> My guess: because he wants to know why this one "doesn't work" instead of >> reading: "use this instead". > > I am writing Perl documentation. All these points seem to be missed in the > reference books that I am using, which incidently are extremely big and run > into several thousand pages each and cost me quite a few quid. > > It seems strange that if I increment $l (which equals 'z') then I now have a > value that is comparitively less than 'z'. > > This looks like a bug to me, at least in the context of an a to z loop. > Probably because you are thinking "for $x := 'a' to 'z'" but writing something completely different. In my view, you *don't* have an a to z loop. You have an initializer; loop-test; counting-expression loop. I've always disliked them, I find they're mostly used for shooting yourself in the foot or doing something more clearly expressed as a foreach or numeric-range loop. http://en.wikipedia.org/wiki/For_loo...s_of_for_loops Saying "in the context of" suggests that you'd like 'z' le 'aa' to sometimes return true and sometimes return false depending in whether the expression was being evaluated in the context of a for loop or not. I think that would be a bad thing. In the code below the value returned by my inorder subroutine would have to depend on whether it was called from an expression that was part of a for loop. This would be horribly hard to justify. #!perl use strict; use warnings; if (inorder('aa','z')) { print 'ordered OK'; } for (my $x='x'; inorder($x, 'z'); $x++) { print $x,' '; } sub inorder { my ($p, $q) = @_; $p le $q; } And of course, if you are using a three-part for loop to sort a dictionary you'd want the current behaviour of the le operator even in the context of a for loop. |
Re: Ascii characters in a loop
John Bokma <john@castleamber.com> wrote:
> for ($l = 'a'; $l ne 'aa'; $l++) { > print "$l"; > } Yeah! I just think that 'a to z' looks far nicer late on a Friday night when I am trying to debug code. I need to test reverse loops, capitals, jumping by more than one letter at a time now to see if there are any more nasty surprises. I often loop through alphabetical sequences in code. Regards, Mark. -- Mark Hobley 393 Quinton Road West QUINTON Birmingham B32 1QE Telephone: (0121) 247 1596 International: 0044 121 247 1596 Email: markhobley at hotpop dot donottypethisbit com http://markhobley.yi.org/ |
| All times are GMT. The time now is 01:38 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.