Reputation: 1830
Why second output shows me only one element of Array
? Is it still Array
or Hash
already?
def printArray(arr)
arr.each { | j |
k, v = j.first
printf("%s %s %s \n", k, v, j)
}
end
print "Array 1\n"
printArray( [
{kk: { 'k1' => 'v1' }},
{kk: { 'k2' => 'v2' }},
{kk: { 'k3' => 'v3' }},
])
print "Array 2\n"
printArray( [
kk: { 'k1' => 'v1' },
kk: { 'k2' => 'v2' },
kk: { 'k3' => 'v3' },
])
exit
# Output:
#
# Array 1
# kk {"k1"=>"v1"} {:kk=>{"k1"=>"v1"}}
# kk {"k2"=>"v2"} {:kk=>{"k2"=>"v2"}}
# kk {"k3"=>"v3"} {:kk=>{"k3"=>"v3"}}
# Array 2
# kk {"k3"=>"v3"} {:kk=>{"k3"=>"v3"}}
Upvotes: 0
Views: 907
Reputation: 29941
Ruby interpreted the second example as an array with a single hash as its element (the curly braces are implied). It is equivalent to this:
[{ kk: { 'k1' => 'v1' }, kk: { 'k2' => 'v2' }, kk: { 'k3' => 'v3' }}]
Only the last 'kk'
is shown because hashes can't have duplicate keys; only the last one sticks.
If you want an array with multiple hashes as elements, you need to use the syntax like on your first example.
More examples on which ruby implies a hash start:
# Only argument on method calls
def only_arg(obj)
puts obj.class
end
only_arg(bar: "baz") # => Hash
# Which is equivalent to:
only_arg({bar: "baz"}) # => Hash
# Last argument on method calls
def last_arg(ignored, obj)
puts obj.class
end
last_arg("ignored", bar: "baz") # => Hash
# Which is equivalent to:
last_arg("ignored", { bar: "baz" }) # => Hash
# Last element on an array
def last_on_array(arr)
puts arr.last.class
end
last_on_array(["something", "something", bar: "baz"]) # => Hash
# Which is equivalent to:
last_on_array(["something", "something", { bar: "baz" }]) # => Hash
Upvotes: 5