Other than hashes as last argument, you can drop parenthesis in Ruby on method invocations and get consistent results (you still have to mind the priority).
However, I encountered an example where this is not the case:
''.split(/ ./) # => []
''.split /./ # => []
''.split / ./ # !> SyntaxError: unexpected '.'
Is this a bug/regression (I tested it with 2.1.2 -> 2.4.1 Rubys)?
Are there other generic cases where dropping the parens doesn't work as expected?
Reported it, lets see.
Update: The ticket was rejected a bit ambiguously. It's not clear if it's a bug or not, but it won't get fixed and using %r{}
in these situations was suggested. The cause is indeed that the opening slash is interpreted as division.
In addition to thesecretmaster's answer, let's take a look inside the Ruby parser:
require 'ripper'
require 'pp'
pp Ripper.lex("''.split /./")
# [[[1, 0], :on_tstring_beg, "'" ],
# [[1, 1], :on_tstring_end, "'" ],
# [[1, 2], :on_period, "." ],
# [[1, 3], :on_ident, "split"],
# [[1, 8], :on_sp, " " ],
# [[1, 9], :on_regexp_beg, "/" ],
# [[1, 10], :on_tstring_content, "." ],
# [[1, 11], :on_regexp_end, "/" ]]
Adding a space makes Ruby recognize the /
characters as division operators:
pp Ripper.lex("''.split / ./")
# [[[1, 0], :on_tstring_beg, "'" ],
# [[1, 1], :on_tstring_end, "'" ],
# [[1, 2], :on_period, "." ],
# [[1, 3], :on_ident, "split"],
# [[1, 8], :on_sp, " " ],
# [[1, 9], :on_op, "/" ],
# [[1, 10], :on_sp, " " ],
# [[1, 11], :on_period, "." ],
# [[1, 12], :on_op, "/" ]]
Are there other generic cases where dropping the parens doesn't work as expected?
Contrived example:
def foo(i = 1)
10 * i
end
foo(- 2) #=> -20
foo - 2 #=> 8
Another one:
b = 2
def a(arg)
arg
end
a *b #=> 2
a = 5
a *b #=> 10
The first a *b
is interpreted as a(*b)
, whereas the second becomes a * b
. Adding parentheses forces Ruby to invoke the method:
a(*b) #=> 2
While this certainly seems like an issue, it isn't a very significant one because \s
in regex will catch spaces. For example:
''.split(/ ./) # => []
''.split /./ # => []
''.split / ./ # !> SyntaxError: unexpected '.'
''.split /\s./ # => []
Or if you want to match only a space you just have to propperly escape it:
''.split /\ ./ # => []
Ruby should parse the arguments the same inside or outside parens, so I'd file a bug, but it's not very urgent and the ruby people may be happy simply leaving it.
Actually, @Stefan mentioned in comments to the questions that it's probably the parser reading it as devision, which is the most likely explanation, so it's not even a bug. But it's one of those fun little ruby quirks.
@Stefan also added that you can create an unambiguous regex literal with the %r{ .}
syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With