Bug #11156
closedIndeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
Description
Given a function that takes an argument and a block, the behavior wildly varies when parenthesis are omitted from the functions argument.
Consider the following function:
require 'time'
def example(arg)
puts arg
if block_given?
puts yield
else
puts "no block"
end
end
Each of the following example sets presents one example
call with parentheses explicitly defined and one whether the parenthesis are omitted.
For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing parenthesis causes a syntax error.
example(1) { "block" }
# 1
# block
example 1 { "block" }
# SyntaxError: syntax error, unexpected '{', expecting end-of-input
Array literals, however, succeed:
example([1]) { "block" }
# 1
# block
example [1] { "block" }
# 1
# block
Identifiers are called as methods if parentheses are omitted:
example(Time) { "block "}
# Time
# block
example Time { "block" }
# NoMethodError: undefined method `Time' for main:Object
a = 1
example(a) { "block" }
# 1
# block
example a { "block" }
# NoMethodError: undefined method `a' for main:Object
Object with method calls simply skip the block when no parenthesis are present:
example(Time.now) { "block" }
# 2015-05-15 18:16:50 -0400
# block
example Time.now { "block" }
# 2015-05-15 18:16:50 -0400
# no block
Method calls with arguments behave about the same as the above...
example(Integer(1)) { "block" }
# 1
# block
example Integer(1) { "block" }
# 1
# no block
...except Time.parse
gets weird:
example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
# 2015-01-01 00:00:00 +0000
# block
# => nil
example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
# 0000-01-01 00:00:00 +0000 <---- Year 2000?!
# no block
# => nil
The lack of consistency across these use cases is extremely confusing and misleading. I'm of the opinion that parentheses omission should, in all cases, lead to a syntax error.