Ascii characters in a loop

Discussion in 'Perl Misc' started by Mark Hobley, Jan 13, 2007.

  1. Mark Hobley

    Mark Hobley Guest

    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/
    Mark Hobley, Jan 13, 2007
    #1
    1. Advertising

  2. 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, Jan 14, 2007
    #2
    1. Advertising

  3. 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,
    RedGrittyBrick, Jan 14, 2007
    #3
  4. Mark Hobley

    Mark Donovan Guest

    On 1/13/07 16:04, in article , "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:
    >
    > 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
    Mark Donovan, Jan 14, 2007
    #4
  5. Mark Hobley

    John Bokma Guest

    Mark Donovan <> wrote:

    > On 1/13/07 16:04, in article ,
    > "Mark Hobley" <> 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, Jan 14, 2007
    #5
  6. Mark Hobley

    John Bokma Guest

    RedGrittyBrick <> 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/
    John Bokma, Jan 14, 2007
    #6
  7. Mark Hobley

    Mark Hobley Guest

    John Bokma <> 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/
    Mark Hobley, Jan 14, 2007
    #7
  8. Mark Hobley

    Dr.Ruud Guest

    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."
    Dr.Ruud, Jan 14, 2007
    #8
  9. Mark Hobley wrote:
    > John Bokma <> 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_loop#Kinds_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.
    RedGrittyBrick, Jan 14, 2007
    #9
  10. Mark Hobley

    Mark Hobley Guest

    John Bokma <> 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/
    Mark Hobley, Jan 14, 2007
    #10
  11. Mark Hobley

    Mark Hobley Guest

    Dr.Ruud <> wrote:

    > Better mention what you do want.


    I am documenting Perl and at the moment I am documenting loops, so I need to
    know any place where choosing a particular value will cause different behaviour
    than choosing another value.

    I often use alphabetical increments in code, so anywhere that choosing a
    particular values for alphabetical ranges requires a change in syntax to
    perform across those range needs to be noted.

    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/
    Mark Hobley, Jan 14, 2007
    #11
  12. Mark Hobley

    Uri Guttman Guest

    >>>>> "MH" == Mark Hobley <> writes:


    MH> I am documenting Perl and at the moment I am documenting loops, so
    MH> I need to know any place where choosing a particular value will
    MH> cause different behaviour than choosing another value.

    what is this 'documenting perl'? perl IS documented and very well at
    that. and there are tons of books about perl. what do you expect to
    bring to the table and make it worthy of reading?

    MH> I often use alphabetical increments in code, so anywhere that choosing a
    MH> particular values for alphabetical ranges requires a change in syntax to
    MH> perform across those range needs to be noted.

    there is no need to worry about this if you understand the rules of
    magic incrementing strings. they are well documented under ++ and .. in
    perlop. and in general it makes little sense to code them using c style
    for loops. (in fact c style for loops are RARELY needed in perl). use
    ... for looping over a range of incrementing strings.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 14, 2007
    #12
  13. Mark Hobley

    Uri Guttman Guest

    >>>>> "MH" == Mark Hobley <> writes:

    MH> John Bokma <> wrote:
    >> for ($l = 'a'; $l ne 'aa'; $l++) {
    >> print "$l";
    >> }


    MH> Yeah! I just think that 'a to z' looks far nicer late on a Friday
    MH> night when I am trying to debug code.

    MH> I need to test reverse loops, capitals, jumping by more than one
    MH> letter at a time now to see if there are any more nasty surprises.

    what is a reverse loop? perl has no such beast. perldoc perlop covers
    magic increment, have you read it?

    MH> I often loop through alphabetical sequences in code.

    then you must be the odd one. i rarely do and i rarely see it. it is
    useful and i use it but often??

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 14, 2007
    #13
  14. Mark Hobley

    John Bokma Guest

    (Mark Hobley) wrote:

    > This looks like a bug to me, at least in the context of an a to z
    > loop.


    I am sure most will call it a feature, that 'z'++ goes to 'aa'.

    As for loops, the form you use is in my experience very rare. I would have
    used:

    for my $l ( 'a' .. 'z' ) {

    }

    Less cluter, and much easier to understand.

    --
    John Experienced Perl programmer: http://castleamber.com/

    Perl help, tutorials, and examples: http://johnbokma.com/perl/
    John Bokma, Jan 14, 2007
    #14
  15. On 2007-01-14 10:04, Mark Hobley <> wrote:
    > John Bokma <> 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'.


    That's because the "le" operator doesn't define "less" and "greater" in
    the same sense as "++" increments. The same happens if you use numbers:

    for (my $l = 0; $l le 9; $l++) {
    print "$l ";
    }

    prints

    0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
    27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
    51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
    75 76 77 78 79 80 81 82 83 84 85 86 87 88 89

    Because 90 is the first number which is greater than 9 in a string
    comparison.

    Only with numbers there is a simple solution (use "<=" instead of "le"),
    while there is no builtin comparison operator for "alphanumeric
    numbers".

    hp


    --
    _ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
    |_|_) | Sysadmin WSR | > ist?
    | | | | Was sonst wäre der Sinn des Erfindens?
    __/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd
    Peter J. Holzer, Jan 14, 2007
    #15
  16. Mark Hobley

    Mark Hobley Guest

    Uri Guttman <> wrote:

    > what is a reverse loop?


    I meant a decremental loop that goes from a higher value to a lower one.

    perl has no such beast. perldoc perlop covers
    > magic increment, have you read it?


    I have now, but I don't think it is really that clear.

    > MH> I often loop through alphabetical sequences in code.
    > then you must be the odd one. i rarely do and i rarely see it.


    I write educational software, games, data processing and back-end stuff. Maybe
    they are more prevalent in these.

    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/
    Mark Hobley, Jan 14, 2007
    #16
  17. Mark Hobley

    Mark Hobley Guest

    Uri Guttman <> wrote:
    >
    > what is this 'documenting perl'? perl IS documented and very well at
    > that. and there are tons of books about perl. what do you expect to
    > bring to the table and make it worthy of reading?


    Tutorial stuff really. I have read tutorials, but I keep finding quirky
    behaviour that the tutorials forgot to mention.

    I don't like perldoc. It is difficult to digest, and doesn't give enough
    examples, and the reference books that I have spent a small fortune on, don't
    mention some of the pitfalls that I am encountering.

    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/
    Mark Hobley, Jan 14, 2007
    #17
  18. Mark Hobley

    Uri Guttman Guest

    >>>>> "MH" == Mark Hobley <> writes:

    MH> Uri Guttman <> wrote:
    >>
    >> what is this 'documenting perl'? perl IS documented and very well at
    >> that. and there are tons of books about perl. what do you expect to
    >> bring to the table and make it worthy of reading?


    MH> Tutorial stuff really. I have read tutorials, but I keep finding
    MH> quirky behaviour that the tutorials forgot to mention.

    almost all perl tutes on the web suck donkey dick. everytime i hear of
    one i check it out and see how fast i can find stupid bugs and
    comments. i have rarely been disappointed. in my future copious spare
    time i will make a page of perl tutes hall of shame.

    MH> I don't like perldoc. It is difficult to digest, and doesn't give
    MH> enough examples, and the reference books that I have spent a small
    MH> fortune on, don't mention some of the pitfalls that I am
    MH> encountering.

    you don't understand that perldoc is documentation and not tutorial. but
    there are a fair number of tutes in there now.

    just as a warning to you, writing perl tutes is not easy (witness all
    the bad ones out there). if you have trouble reading and comprehending
    the existing docs (as with your magic increment issue) bodes poorly for
    your proposed tute. i could be wrong but the odds are with me. i know
    many perl book authors and how sharp they are and how much perl they
    know. to write a tute you need to know more perl than most hackers,
    write extremely well, be able to express concepts clearly, concisely and
    have plenty of good examples. this is a tough task for anyone.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 14, 2007
    #18
  19. Mark Hobley

    Dr.Ruud Guest

    Mark Hobley schreef:


    > I don't like perldoc. It is difficult to digest, and doesn't give
    > enough examples, and the reference books that I have spent a small
    > fortune on, don't mention some of the pitfalls that I am encountering.


    Actually a nice title for an article: Perl Pitfalls. Last week (and not
    here) we discussed Tropical Perl, a book about how far you can get with
    Perl in a don't-worry-be-happy style. Perl Pitfalls can be about things
    like using 'le' when you shouldn't and about how to solidly spoil the
    value of $_ && about how to be bitten best by binops.

    --
    Affijn, Ruud

    "Gewoon is een tijger."
    Dr.Ruud, Jan 14, 2007
    #19
  20. Mark Hobley

    Uri Guttman Guest

    >>>>> "MH" == Mark Hobley <> writes:

    MH> perl has no such beast. perldoc perlop covers
    >> magic increment, have you read it?


    MH> I have now, but I don't think it is really that clear.

    clear to me.

    The auto-increment operator has a little extra builtin magic
    to it. If you increment a variable that is numeric, or that
    has ever been used in a numeric context, you get a normal
    increment. If, however, the variable has been used in only
    string contexts since it was set, and has a value that is
    not the empty string and matches the pattern
    "/^[a-zA-Z]*[0-9]*\z/", the increment is done as a string,
    preserving each character within its range, with carry:

    print ++($foo = '99'); # prints '100'
    print ++($foo = 'a0'); # prints 'a1'
    print ++($foo = 'Az'); # prints 'Ba'
    print ++($foo = 'zz'); # prints 'aaa'

    what part of that do you find unclear? it shows the rollover case in
    numeric and similarly to your example with zz -> aaa.

    MH> I often loop through alphabetical sequences in code.
    >> then you must be the odd one. i rarely do and i rarely see it.


    MH> I write educational software, games, data processing and back-end
    MH> stuff. Maybe they are more prevalent in these.

    i doubt that. i have coded many different projects and don't see string
    increment being needed often. but you could be using the only hammer you
    have to work on different nails. i see that all the time.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
    Uri Guttman, Jan 14, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laszlo Nagy
    Replies:
    6
    Views:
    599
  2. Terry Reedy
    Replies:
    0
    Views:
    497
    Terry Reedy
    Jul 1, 2008
  3. M.-A. Lemburg
    Replies:
    0
    Views:
    879
    M.-A. Lemburg
    Jul 2, 2008
  4. Alextophi
    Replies:
    8
    Views:
    482
    Alan J. Flavell
    Dec 30, 2005
  5. Isaac Won
    Replies:
    9
    Views:
    350
    Ulrich Eckhardt
    Mar 4, 2013
Loading...

Share This Page