and and or in case

P

Peña, Botp

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
 
B

Ben Brightwell

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

Peña, Botp

RnJvbTogUGXDsWEsIEJvdHAgW21haWx0bzpib3RwQGRlbG1vbnRlLXBoaWwuY29tXSANCiMgaWYg
MT09MSBhbmQgMj09Mg0KIyAgIHAgIm9rIg0KIyBlbmQNCiMgIm9rIg0KIyAjPT4gbmlsDQojIA0K
IyBjYXNlDQojIHdoZW4gMT09MSBhbmQgMj09Mg0KIyAgIHAgIm9rIg0KIyBlbmQNCiMgU3ludGF4
RXJyb3I6IGNvbXBpbGUgZXJyb3INCg0Kbm90ZSwgd2hlbiBpIHVzZSBwYXJlbnMgKHRvIG92ZXJy
aWRlKSwgaXQgd29ya3MNCg0KY2FzZQ0Kd2hlbiAoMT09MSBhbmQgMj09MikNCiAgcCAib2siDQpl
bmQNCiJvayINCiM9PiBuaWwNCg0KDQpidXQgc3RpbGwgaXQgZG9lcyBub3QgYW5zd2VyIHRoZSBk
aWZmZXJlbmNlIGluIGJlaGF2aW91ciB0byB0aGF0IG9mIG9yZGluYXJ5IGlmLWVsc2lmIGNsYXVz
ZS4uLg0KDQoNCg==
 
A

Alex Gutteridge

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

Robert Klemme

2008/7/29 Pe=F1a said:
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 <<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
 
B

botp

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
 
R

reuben doetsch

[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
 
A

Alex Gutteridge

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
 
P

Peña, Botp

From: Dr A. Gutteridge [mailto:[email protected]] 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 :)
 
D

Derek Taylor

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:
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.
 
T

Thomas Wieczorek

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top