Syntax bug, in 1.8.5? return not (some expr) <-- syntax error vsreturn (not (some expr)) <-- fine

G

Good Night Moon

Well, it's all in the subject, to me it looks like a parsing bug:

class MyRect
def intersects_good(other)
return (not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0)))
end

def intersects_bad(other)
return not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0))
end
end

foo> ruby -c myrect.rb
myrect.rb:8: syntax error, unexpected kNOT, expecting kEND
return not ((other.x1 < self.x0 or self.x1 < other.x0) and
^

Any comment? Is this known? Or just some hair in the Ruby grammar?
 
B

Bil Kleb

Good said:
myrect.rb:8: syntax error, unexpected kNOT, expecting kEND
return not ((other.x1 < self.x0 or self.x1 < other.x0) and

You need to use the '!' operator instead of the 'not' "conjunction".
It's a precedence thing -- the parser is seeing 'return not' -- see
parse.y in the source.

Regards,
 
S

Sharon Phillips

Well, it's all in the subject, to me it looks like a parsing bug:

class MyRect
def intersects_good(other)
return (not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0)))
end

def intersects_bad(other)
return not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0))
end
end

foo> ruby -c myrect.rb
myrect.rb:8: syntax error, unexpected kNOT, expecting kEND
return not ((other.x1 < self.x0 or self.x1 < other.x0) and
^

Any comment? Is this known? Or just some hair in the Ruby grammar?

There's a difference between [not, and, or] and [!, &&, ||]
Not sure what it is, but I've found it better to use the latter.
Still, if you wrap the whole statement in another set of brackets
(like intersects_good) it will work.

def intersects_bad(other)
return (not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0)))
end

by the way, what's the difference between the two methods? They
appear identical.

Cheers,
Dave
 
G

Good Night Moon

You need to use the '!' operator instead of the 'not' "conjunction".
It's a precedence thing -- the parser is seeing 'return not' -- see
parse.y in the source.

Thanks, maybe I'll look. It's not just precedence though, or else
'return' itself is part of it:

def ok
return (not true)
end

def fails
return not true
end

And note that within an 'if', it works as you'd expect:

def with_parens_ok
if (not true)
puts "not true"
end
end

def no_parens_ok
if not true
puts "not true"
end
end
 
G

Good Night Moon

There's a difference between [not, and, or] and [!, &&, ||] Not sure
what it is, but I've found it better to use the latter. Still, if you
wrap the whole statement in another set of brackets (like
intersects_good) it will work.

def intersects_bad(other)
return (not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0)))
end

by the way, what's the difference between the two methods? They appear
identical.

Thanks. The difference is just to point out what looks like
a bug; the parens shouldn't make a difference. Look at
my other reply in this thread for elaboration.
 
D

dblack

Hi --

There's a difference between [not, and, or] and [!, &&, ||] Not sure
what it is, but I've found it better to use the latter. Still, if you
wrap the whole statement in another set of brackets (like
intersects_good) it will work.

def intersects_bad(other)
return (not ((other.x1 < self.x0 or self.x1 < other.x0) and
(other.y1 < self.y0 or self.y1 < other.y0)))
end

by the way, what's the difference between the two methods? They appear
identical.

Thanks. The difference is just to point out what looks like
a bug; the parens shouldn't make a difference. Look at
my other reply in this thread for elaboration.

I don't think it's a bug. Have a look at these examples:

def x; return 1 and puts "I'm gone!"; end
SyntaxError: compile error
(irb):3: void value expression

def x; 2 not 3; end
SyntaxError: compile error
(irb):5: syntax error, unexpected kNOT, expecting kEND

These both make sense. 'and' is right-associative, so you're trying
to do something after having already returned, which doesn't work.
And in general you can't do "x not y", which is what "return not ..."
is read as.


David

--
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
 
G

Gregory Brown

Thanks, maybe I'll look. It's not just precedence though, or else
'return' itself is part of it:

if binds differently than return. It is precedence.
 
R

Roger Pack

I agree that
if not File.exists? "a"
do stuff
end

would be nice intuitively. I wish...
 
F

F. Senault

Le 24 juillet 2007 à 00:22, Roger Pack a écrit :
I agree that
if not File.exists? "a"
do stuff
end

would be nice intuitively. I wish...

unless File.exists? "a"
do stuff
end

do stuff unless File.exists? "a"

Isn't it even more intuitive ?

Fred
 
R

Rick DeNatale

if binds differently than return. It is precedence.

Except that return isn't an operator. As far as I can tell, looking
at parse.y for ruby1.8.6 the parse tree for the original statement
which raised the question

return not true

should be:

command_call
kRETURN expr
kNOT expr
primary
var_ref
variable
kTRUE

There definitely looks to be something strange here.
 

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

Forum statistics

Threads
474,263
Messages
2,571,312
Members
47,988
Latest member
HarryBeck

Latest Threads

Top