1

I'm learning Ruby, but I'm having trouble predicting what Ruby will behave under certain circumstances. For example, the following causes a syntax error:

[2, 3, 4].any? do |x|
    (x > 1 
    and x < 4)
end

but this compiles fine:

[2, 3, 4].any? do |x|
    (x > 1 and 
    x < 4)
end

(the difference is in the placement of the and)

Why does the former fail to compile, while the latter succeeds, and how would I have known that? i.e.: since the above seems totally unintuitive, where is the formal grammar for Ruby, like https://docs.python.org/3/reference/grammar.html , or a guide like this https://docs.python.org/3/reference/lexical_analysis.html so I don't have to just guess at Ruby's behavior and figure it out by trial & error?

jensck
  • 154
  • 1
  • 11
  • I can't answer your question on the whitespace/return issue this is causing, I can say that idiomatic ruby prohibits `and, or, not` from conditionals in favor of `&&, ||, !!`. Maybe look at the Ruby style guides [here](https://github.com/bbatsov/ruby-style-guide) for help with syntax stuff. – Anthony Sep 26 '14 at 20:28
  • 1
    [Ruby does does not really have a formal grammar](http://stackoverflow.com/questions/663027/ruby-grammar). [parse.y](https://github.com/ruby/ruby/blob/trunk/parse.y) from the ruby source is as close as it gets. – max Sep 26 '14 at 20:39

2 Answers2

3

You have to end the line with an operator if you want the statement to be continued on the next line.

I will try to see if I can re-find the doc on this.

This is documented in the following book , chapter 2.

The Ruby Programming Language By David Flanagan, Yukihiro Matsumoto

To paraphrase : With having semicolons as explicit end of statement indicators, the ruby interpreter must figure out when a statement ends. It does this by figuring out if a statement is complete or not, if not it continues parsing on the next line. So

total = x +
 y 

is the same as total = x + Y since total = x + is not a complete statement

but

total = x
+y 

is the same as total = x followed by the statement +y, which is just y

so the same applies for a conditional , if you end with a && for example the interpreter will continue parsing on the next line

x = a &&
b

is the same as x = a && b

but

x = a
&& b

is assigns a to x and generates a syntax error for the next line

nPn
  • 16,254
  • 9
  • 35
  • 58
1

Your best friend: CLICK ME

If you would like to format your conditionals like your first example(I don't know why you would) you can use the \format. Try this

[2, 3, 4].any? do |x|
  (x > 1 \
  and x < 4)
end

Basically just add the slash after each Boolean except your last one!

However standard Ruby convention is to be as short, descriptive, and concise as possible. A similar conditional could be written as so

As johnson said it should be

[2, 3, 4].any? { |x| x > 1 && x < 4 }

Happy Coding!

Schylar
  • 774
  • 1
  • 5
  • 13
  • Right on with both the link and the first code block. But your second and third code blocks don't adhere to the purpose of `Enumberable#any?` which is just supposed to return a Boolean on the evaluation of your block. So it should be: `[2, 3, 4].any? { |x| x > 1 && x < 4 }`. If he wants to put the element or do something with each element, he should use `#each`. – Johnson Sep 26 '14 at 21:26
  • I didn't take the time to checkout `any?` But I was just mainly trying to emphasize using code blocks instead of `do` for small conditions and using the `&&` because `and` should be used for control flow. – Schylar Sep 26 '14 at 21:53