I was reading this SO question: https://stackoverflow.com/a/4402761/2379703 and the last post showing the rails render
impl was interesting. It's signature is:
def render(options = {}, locals = {}, &block)
If the first argument is a plain string, it assigns that to options and the rest is interpreted as a hash and assigned to locals. For example:
render('partial_name', key: 'value', key2:, 'value2')
Which results in:
options = "partial_name"
locals = {key: 'value', key2:, 'value2'}
If you just pass key/value pairs, it assumes you passed a single argument of a hash and assigns it all to options and leaves locals empty:
render(partial: 'partial_name', key: 'value', key2", 'value2')
Which results in:
options = {partial: 'partial_name', key: 'value', key2:, 'value2'}
locals = {}
So my question really comes down to is: What is the logic that ruby uses to figure out which parameter gets assigned what when there are multiple optional parameters? Furthermore, it seems that hashes make the answer to this question more interesting since hashes clearly don't need to be delimited with outer {} when passed in as arguments.
A secondary observation, in a test where I used the same signature for a test method like render, and I passed the following in:
render(key: 'value', key2: 'value2', 'string')
And that results in a syntax error:
test_hash_param.rb:15: syntax error, unexpected ')', expecting =>
Why is this? Why doesn't it assign the two key/value pairs to options and sets locals to 'string'?
However this works as I assumed it would:
render({key: 'value', key2: 'value2'}, 'string')