and and or in case

Discussion in 'Ruby' started by Peña, Botp, Jul 29, 2008.

  1. Peña, Botp

    Peña, Botp Guest

    Hi All, apologies in advanced if this has been discussed already

    why does ruby not compile the following case-when clause if using "and" =
    or "or" ? It works if i replace it with "&&" or "||", but i'm not asking =
    nor using that, "and/or" are much friendlier.

    samples,

    irb(main):038:0> case
    irb(main):039:1* when 1=3D=3D1 or 2=3D=3D2
    irb(main):040:1> puts "ok"
    irb(main):041:1> end
    SyntaxError: compile error
    (irb):39: syntax error, unexpected kOR, expecting kTHEN or ':' or '\n' =
    or ';'
    when 1=3D=3D1 or 2=3D=3D2
    ^
    (irb):41: syntax error, unexpected kEND, expecting $end
    from (irb):41
    from ?:0

    irb(main):050:0> case
    irb(main):051:1* when 1=3D=3D1 and 2=3D=3D2
    irb(main):052:1> puts "ok"
    irb(main):053:1> end
    SyntaxError: compile error
    (irb):51: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' =
    or ';'
    when 1=3D=3D1 and 2=3D=3D2
    ^
    (irb):53: syntax error, unexpected kEND, expecting $end
    from (irb):53
    from :0

    thank you and kind regards -botp
     
    Peña, Botp, Jul 29, 2008
    #1
    1. Advertising

  2. Peña,

    The way I see it (and also the way I practice it today) is to always
    always always use "&&" or "||" over "and" or "or", respectively.

    The words "and" and "or" are lower in the order of operators than the
    symbols "&&" and "||". This is intentional for beginner programmers to
    be able to "read" the code rather than work out the logic of the code.
    Take this for an example:

    When using the symbolic operator "||", ruby sees what you write like
    this:

    case
    (when (1==1 || 2==2)) # good "when" keyword and good expression to
    satisfy it
    puts "ok"
    end

    This is good syntax, and gives the "when" keyword what it is looking
    for, an expression.

    When using the word operator "or", ruby sees it like this:

    case
    (when 1==1) or (2==2) # good "when" keyword, expression, but then
    additional "or" keyword
    puts "ok"
    end

    While this reads ok in language, it doesn't quite work for ruby. Because
    the word "or" gets tried lower in the order of operators, it concludes
    the "when" keyword with a satisfactory expression, 1==1. Now the "case"
    keyword is satisfied with a proper "when" keyword. Ruby throws up its
    red flag when it sees something else past the good expression. To ruby
    this would be likewise -wrong- to do:

    case
    (when (1==1 || 2==2)) or (3==3)
    puts "ok"
    end

    It's all good until the additional "or" keyword.

    Just remember that ruby sees the "&&"/"||" and "and"/"or" as completely
    different operators.
    --
    Posted via http://www.ruby-forum.com/.
     
    Ben Brightwell, Jul 29, 2008
    #2
    1. Advertising

  3. RnJvbTogUGXDsWEsIEJvdHAgW21haWx0bzpib3RwQGRlbG1vbnRlLXBoaWwuY29tXSANCiMgaWYg
    MT09MSBhbmQgMj09Mg0KIyAgIHAgIm9rIg0KIyBlbmQNCiMgIm9rIg0KIyAjPT4gbmlsDQojIA0K
    IyBjYXNlDQojIHdoZW4gMT09MSBhbmQgMj09Mg0KIyAgIHAgIm9rIg0KIyBlbmQNCiMgU3ludGF4
    RXJyb3I6IGNvbXBpbGUgZXJyb3INCg0Kbm90ZSwgd2hlbiBpIHVzZSBwYXJlbnMgKHRvIG92ZXJy
    aWRlKSwgaXQgd29ya3MNCg0KY2FzZQ0Kd2hlbiAoMT09MSBhbmQgMj09MikNCiAgcCAib2siDQpl
    bmQNCiJvayINCiM9PiBuaWwNCg0KDQpidXQgc3RpbGwgaXQgZG9lcyBub3QgYW5zd2VyIHRoZSBk
    aWZmZXJlbmNlIGluIGJlaGF2aW91ciB0byB0aGF0IG9mIG9yZGluYXJ5IGlmLWVsc2lmIGNsYXVz
    ZS4uLg0KDQoNCg==
     
    Peña, Botp, Jul 29, 2008
    #3
  4. On 29 Jul 2008, at 08:47, Pe=F1a, Botp wrote:

    > From: Ben Brightwell [mailto:]
    > # The way I see it (and also the way I practice it today) is to always
    > # always always use "&&" or "||" over "and" or "or", respectively.
    > # The words "and" and "or" are lower in the order of operators than =20=


    > the
    > # symbols "&&" and "||". This is intentional for beginner
    > # programmers to be able to "read" the code rather than work out the
    > # logic of the code.
    >
    > Ben thanks, but i'm not convinced. It still does not answer why it =20
    > is not allowing in case-when clause yet allowing it in if-elsif,


    The point is that case/when has different precedence to if/elsif. The =20=

    Pickaxe precedence table doesn't mention case/when, but the order of =20
    the others is given as:

    &&
    ||
    or
    and
    if

    So 'if' has the lowest precedence and any combination of and/or/&&/|| =20=

    will be taken first before applying the 'if'. We can assume from your =20=

    results that 'case/when' has a precedence between &&/|| and and/or:

    &&
    ||
    case/when
    or
    and
    if

    So the statement

    case
    when 1=3D=3D1 and 2=3D=3D2: p 'ok'
    end

    is parsed as

    case
    (when 1=3D=3D1) and 2=3D=3D2: p 'ok'
    end

    Which is a syntax error. While

    case
    when 1=3D=3D1 && 2=3D=3D2: p 'ok'
    end

    is parsed correctly as:

    case
    when (1=3D=3D1 && 2=3D=3D2): p 'ok'
    end

    Which as you note is fine syntax. Since 'if' has the lowest precedence,

    if 1=3D=3D1 and 2=3D=3D2 then p 'ok' end

    is always (whether you use 'and' or &&) parsed as

    if (1=3D=3D1 and 2=3D=3D2) then p 'ok' end

    > sample,
    >
    > if 1=3D=3D1 and 2=3D=3D2
    > p "ok"
    > end
    > "ok"
    > #=3D> nil
    >
    > case
    > when 1=3D=3D1 and 2=3D=3D2
    > p "ok"
    > end
    > SyntaxError: compile error
    > (irb):5: syntax error, unexpected kAND, expecting kTHEN or ':' or =20
    > '\n' or ';'
    > when 1=3D=3D1 and 2=3D=3D2
    > ^
    > (irb):7: syntax error, unexpected kEND, expecting $end
    > from (irb):7
    > from :0
    >
    > arggh, i love using case-when and and/or and now both do not work =20
    > together?? quite a surprise to me there.
    >
    > kind regards -botp



    They work, but you have to accept that you need to play very close =20
    attention to precedence when you use them and that parens may be =20
    necessary to get what you want.

    Alex Gutteridge

    Department of Biochemistry
    University of Cambridge
     
    Alex Gutteridge, Jul 29, 2008
    #4
  5. 2008/7/29 Pe=F1a, Botp <>:
    > From: Ben Brightwell [mailto:]
    > # The way I see it (and also the way I practice it today) is to always
    > # always always use "&&" or "||" over "and" or "or", respectively.
    > # The words "and" and "or" are lower in the order of operators than the
    > # symbols "&&" and "||". This is intentional for beginner
    > # programmers to be able to "read" the code rather than work out the
    > # logic of the code.
    >
    > Ben thanks, but i'm not convinced. It still does not answer why it is not=

    allowing in case-when clause yet allowing it in if-elsif,

    The answer is the precedence defined into the syntax.

    15:13:04 oz-27416_Failed_to_lock_accounts$ ruby -c <<XXX
    > case
    > when a > b || c < d
    > puts 1
    > end
    > XXX

    Syntax OK
    17:05:28 oz-27416_Failed_to_lock_accounts$ ruby -c <<XXX
    > case
    > when a > b or c < d
    > puts 1
    > end
    > XXX

    -:2: syntax error, unexpected kOR, expecting kTHEN or ':' or '\n' or ';'
    when a > b or c < d
    ^
    -:4: syntax error, unexpected kEND, expecting $end
    17:06:46 oz-27416_Failed_to_lock_accounts$


    > sample,
    >
    > if 1=3D=3D1 and 2=3D=3D2
    > p "ok"
    > end
    > "ok"
    > #=3D> nil
    >
    > case
    > when 1=3D=3D1 and 2=3D=3D2
    > p "ok"
    > end
    > SyntaxError: compile error
    > (irb):5: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or=

    ';'
    > when 1=3D=3D1 and 2=3D=3D2
    > ^
    > (irb):7: syntax error, unexpected kEND, expecting $end
    > from (irb):7
    > from :0
    >
    > arggh, i love using case-when and and/or and now both do not work togethe=

    r?? quite a surprise to me there.

    Note though that you can have your "or" differently in a "case" expression:

    17:06:46 oz-27416_Failed_to_lock_accounts$ ruby -c <<XXX
    > case
    > when a > b, c < d
    > puts 1
    > end
    > XXX

    Syntax OK
    17:08:01 oz-27416_Failed_to_lock_accounts$

    And you can at least do

    17:08:01 oz-27416_Failed_to_lock_accounts$ ruby -c <<XXX
    > case
    > when ( a > b and c < d )
    > puts 1
    > end
    > XXX

    Syntax OK


    Kind regards

    robert

    --=20
    use.inject do |as, often| as.you_can - without end
     
    Robert Klemme, Jul 29, 2008
    #5
  6. Peña, Botp

    botp Guest

    On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge
    <> wrote:
    > So 'if' has the lowest precedence and any combination of and/or/&&/|| will
    > be taken first before applying the 'if'. We can assume from your results
    > that 'case/when' has a precedence between &&/|| and and/or:
    > &&
    > ||
    > case/when
    > or
    > and
    > if


    yes, but why the difference in precedence for case-when and if?
    shouldn't it be more natural that they be the same?

    thanks -botp
     
    botp, Jul 29, 2008
    #6
  7. [Note: parts of this message were removed to make it a legal post.]

    yeah make a change to the language then or maybe we should ask matz and then
    make the change if he okays it

    On Tue, Jul 29, 2008 at 10:25 AM, botp <> wrote:

    > On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge
    > <> wrote:
    > > So 'if' has the lowest precedence and any combination of and/or/&&/||

    > will
    > > be taken first before applying the 'if'. We can assume from your results
    > > that 'case/when' has a precedence between &&/|| and and/or:
    > > &&
    > > ||
    > > case/when
    > > or
    > > and
    > > if

    >
    > yes, but why the difference in precedence for case-when and if?
    > shouldn't it be more natural that they be the same?
    >
    > thanks -botp
    >
    >
     
    reuben doetsch, Jul 29, 2008
    #7
  8. On 29 Jul 2008, at 16:25, botp wrote:

    > On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge
    > <> wrote:
    >> So 'if' has the lowest precedence and any combination of and/or/
    >> &&/|| will
    >> be taken first before applying the 'if'. We can assume from your
    >> results
    >> that 'case/when' has a precedence between &&/|| and and/or:
    >> &&
    >> ||
    >> case/when
    >> or
    >> and
    >> if

    >
    > yes, but why the difference in precedence for case-when and if?
    > shouldn't it be more natural that they be the same?
    >
    > thanks -botp



    Why? There is no why. Only 'principle of least surprise' ;)

    Alex Gutteridge

    Department of Biochemistry
    University of Cambridge
     
    Alex Gutteridge, Jul 29, 2008
    #8
  9. Peña, Botp

    Peña, Botp Guest

    From: Dr A. Gutteridge [mailto:] On=20
    # Why? There is no why. Only 'principle of least surprise' ;)

    I thought there was some technical/design concerns/breakage that made =
    matz decide on the ordering/precedence... so no problem then, that's =
    good news.. i hope matz will change his mind :)=20

    kind regards -botp (a ruby case/and/or fan :)
     
    Peña, Botp, Jul 30, 2008
    #9
  10. Peña, Botp

    Derek Taylor Guest

    On Tue, 29 Jul 2008, Pea, Botp wrote:
    >Hi All, apologies in advanced if this has been discussed already
    >
    >why does ruby not compile the following case-when clause if using "and"
    >or "or" ? It works if i replace it with "&&" or "||", but i'm not asking
    >nor using that, "and/or" are much friendlier.


    The operators "and" and "&&" (and likewise "or" and "||") have different
    precedence levels. Things are binding differently than you think that
    they should be.

    >
    >samples,
    >
    >irb(main):038:0> case
    >irb(main):039:1* when 1==1 or 2==2
    >irb(main):040:1> puts "ok"
    >irb(main):041:1> end
    >SyntaxError: compile error
    >(irb):39: syntax error, unexpected kOR, expecting kTHEN or ':' or '\n' or ';'
    >when 1==1 or 2==2
    > ^
    >(irb):41: syntax error, unexpected kEND, expecting $end
    > from (irb):41
    > from ?:0


    Try:
    >> case

    ?> when (1==1 or 2==2)
    >> puts "ok"
    >> end

    ok
    => nil


    >irb(main):050:0> case
    >irb(main):051:1* when 1==1 and 2==2
    >irb(main):052:1> puts "ok"
    >irb(main):053:1> end
    >SyntaxError: compile error
    >(irb):51: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or ';'
    >when 1==1 and 2==2
    > ^
    >(irb):53: syntax error, unexpected kEND, expecting $end
    > from (irb):53
    > from :0
    >
    >thank you and kind regards -botp
    >


    -Derek.
     
    Derek Taylor, Jul 30, 2008
    #10
  11. Hello Botp!

    On Tue, Jul 29, 2008 at 5:25 PM, botp <> wrote:
    >
    > yes, but why the difference in precedence for case-when and if?
    > shouldn't it be more natural that they be the same?
    >


    Yes, I agree with you. I think when and if should act the same, this
    would follow the principle of least suprise.

    I think some might have missed the question:
    Why DOES this work?
    if 1 == 1 and 2 == 2
    puts "OK!"
    end
    # => "OK!"

    Why DOES NOT this work?
    case
    when 1 == 1 and 2 == 2
    puts "OK!"
    end
    syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or ';'
    when 1 == 1 and 2 == 2
    ^
    test.rb:9: syntax error, unexpected kEND, expecting $end


    The precedence seems to be handled differently with "if" and "when".

    Regards, Thomas
     
    Thomas Wieczorek, Jul 30, 2008
    #11
    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. Steve Franks
    Replies:
    2
    Views:
    1,273
    Steve Franks
    Jun 10, 2004
  2. Tee
    Replies:
    3
    Views:
    7,884
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  3. Janice

    lower case to upper case

    Janice, Dec 10, 2004, in forum: C Programming
    Replies:
    17
    Views:
    1,211
    Richard Bos
    Dec 14, 2004
  4. Replies:
    1
    Views:
    2,525
    Mark P
    Apr 6, 2007
  5. darrel

    'case' vs. 'case is'

    darrel, Aug 14, 2008, in forum: ASP .Net
    Replies:
    3
    Views:
    288
    Rory Becker
    Aug 14, 2008
Loading...

Share This Page