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
from :0

thank you and kind regards -botp

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.

From: Ben Brightwell [mailto:[email protected]]

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

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: Peña, Botp [mailto:[email protected]]

if 1==1 and 2==2

p “ok”

end

“ok”

#=> nil

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…

2008/7/29 Peña, Botp [email protected]:

From: Ben Brightwell [mailto:[email protected]]

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

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

On Tue, Jul 29, 2008 at 5:58 PM, Alex G.
[email protected] 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

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

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

p “ok”
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 G.

Department of Biochemistry
University of Cambridge

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

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

Department of Biochemistry
University of Cambridge

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

From: Dr A. Gutteridge [mailto:[email protected]] On

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:

Hello Botp!

On Tue, Jul 29, 2008 at 5:25 PM, botp [email protected] 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

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.

       ^

(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

   from :0

thank you and kind regards -botp

-Derek.