Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   Ascii characters in a loop (http://www.velocityreviews.com/forums/t901414-ascii-characters-in-a-loop.html)

Mark Hobley 01-13-2007 11:04 PM

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/


RedGrittyBrick 01-14-2007 12:05 AM

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'.

RedGrittyBrick 01-14-2007 12:13 AM

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,

Mark Donovan 01-14-2007 12:39 AM

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



John Bokma 01-14-2007 04:10 AM

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/

John Bokma 01-14-2007 04:12 AM

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/

Mark Hobley 01-14-2007 10:04 AM

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/


Dr.Ruud 01-14-2007 11:33 AM

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."


RedGrittyBrick 01-14-2007 12:59 PM

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.

Mark Hobley 01-14-2007 02:04 PM

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 04:21 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.