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’ 
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’
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 
kind regards -botp (a ruby case/and/or fan 
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.