Inconsistent implicit hash creation in Ruby?

2019-04-25 09:45发布

问题:

Ok, so I was comparing some stuff in my own DSL to Ruby. One construct they both support is this

x=["key" => "value"]

Knowing the difference between arrays and hashes, I would think this to be illegal, but the result in Ruby is

[{"key" => "value"}]

Why is this? And with this kinda syntax why can't you do

x=("key" => "value") 

Why is an array a special case for implicitly created hashes?

回答1:

Another special case is in a function call, consider:

def f(x)
  puts "OK: #{x.inspect}"
end
f("foo" => "bar")
=> OK: {"foo"=>"bar"}

So in some contexts, Hashes can be built implicitly (by detecting the => operator?). I suppose the answer is just that this was Matz's least-surprising behavior.



回答2:

With this apparent inconsistency in implicit hash creation, ruby achieves consistency in this regard:

func(whatever...)

can always be substituted with:

args = [whatever...]
func(*args)

You can convert between argument lists and arrays, and therefore it is logical that they have the same syntax.



回答3:

I would say that the interpreter figures out that "key" => "value" is a hash, the same way it would figure out that 5 is a number when you put it into an array.
So if you write:

x = [5]

The interpreter is not going to think that it is a string, and return:

x = ["5"]

It seems that ruby implicitly creates hashes in some instances.