In the book Rails Test Prescriptions (b10.0, page 176), there are examples of one-liner assertions like the following:
should "be successful" { assert_response :success }
This doesn’t appear to be valid ruby syntax to me, and ruby reports that the left curly brace is unexpected. In order for it to be parsed, I have to change it to
should "be successful"; do assert_response :success end
What's wrong with the syntax of the first example?
This is valid Ruby syntax. Well, sort of. It just doesn't make sense!
Since the precedence of a literal block using curly braces is higher than passing an argument without parentheses, the block gets bound to the argument instead of the method call. If the argument is itself a method call, then you won't even get a syntax error. You'll just scratch your head wondering why your block doesn't get called.
To fix this, you either put parentheses around the argument, since parentheses have higher precedence than curly braces, or use the do
/ end
form, which is lower precedence than an argument list without parentheses.
def foo; yield if block_given?; 'foo' end
puts foo { puts 'block' }
# block
# foo
puts(foo) { puts 'block' }
# foo
puts foo do puts 'block' end
# foo
puts foo { puts 'block' }, foo { puts 'block' }
# block
# block
# foo
# foo
puts 'foo' { puts 'block' }
# SyntaxError: (irb):19: syntax error, unexpected '{', expecting $end