And and or in case

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==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

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

thank you and kind regards -botp

···

from :0

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

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.

···

On Tue, 29 Jul 2008, Pea, Botp wrote:

arggh, i love using case-when and and/or and now both do not work together?? quite a surprise to me there.

kind regards -botp

···

From: Ben Brightwell [mailto:neogia4@gmail.com]
# 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,

sample,

if 1==1 and 2==2
  p "ok"
end
"ok"
#=> nil

case
when 1==1 and 2==2
  p "ok"
end
SyntaxError: compile error
(irb):5: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or ';'
when 1==1 and 2==2
             ^
(irb):7: syntax error, unexpected kEND, expecting $end
        from (irb):7
        from :0

# if 1==1 and 2==2
# p "ok"
# end
# "ok"
# #=> nil

···

From: Peña, Botp [mailto:botp@delmonte-phil.com]
#
# case
# when 1==1 and 2==2
# p "ok"
# end
# SyntaxError: compile error

note, when i use parens (to override), it works

case
when (1==1 and 2==2)
  p "ok"
end
"ok"
#=> nil

but still it does not answer the difference in behaviour to that of ordinary if-elsif clause...

From: Ben Brightwell [mailto:neogia4@gmail.com]
# 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 point is that case/when has different precedence to if/elsif. The Pickaxe precedence table doesn't mention case/when, but the order of the others is given as:

&&

or
and
if

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

So the statement

case
when 1==1 and 2==2: p 'ok'
end

is parsed as

case
(when 1==1) and 2==2: p 'ok'
end

Which is a syntax error. While

case
when 1==1 && 2==2: p 'ok'
end

is parsed correctly as:

case
when (1==1 && 2==2): p 'ok'
end

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

if 1==1 and 2==2 then p 'ok' end

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

if (1==1 and 2==2) then p 'ok' end

sample,

if 1==1 and 2==2
p "ok"
end
"ok"
#=> nil

case
when 1==1 and 2==2
p "ok"
end
SyntaxError: compile error
(irb):5: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or ';'
when 1==1 and 2==2
            ^
(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 together?? quite a surprise to me there.

kind regards -botp

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

Alex Gutteridge

Department of Biochemistry
University of Cambridge

···

On 29 Jul 2008, at 08:47, Peña, Botp wrote:

From: Ben Brightwell [mailto:neogia4@gmail.com]
# 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==1 and 2==2
p "ok"
end
"ok"
#=> nil

case
when 1==1 and 2==2
p "ok"
end
SyntaxError: compile error
(irb):5: syntax error, unexpected kAND, expecting kTHEN or ':' or '\n' or ';'
when 1==1 and 2==2
            ^
(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 together?? 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

···

2008/7/29 Peña, Botp <botp@delmonte-phil.com>:

--
use.inject do |as, often| as.you_can - without end

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

···

On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge <alexg@ruggedtextile.com> 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

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 <botpena@gmail.com> wrote:

On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge > <alexg@ruggedtextile.com> 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' :wink:

Alex Gutteridge

Department of Biochemistry
University of Cambridge

···

On 29 Jul 2008, at 16:25, botp wrote:

On Tue, Jul 29, 2008 at 5:58 PM, Alex Gutteridge > <alexg@ruggedtextile.com> 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

Hello Botp!

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

···

On Tue, Jul 29, 2008 at 5:25 PM, botp <botpena@gmail.com> wrote:

# Why? There is no why. Only 'principle of least surprise' :wink:

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 :slight_smile:

kind regards -botp (a ruby case/and/or fan :slight_smile:

···

From: Dr A. Gutteridge [mailto:ag357@hermes.cam.ac.uk] On