rubyiteratorparallel-assignment

Iterating over list of hashes via parallel assignment


I've just seen this code (simplified):

def something
  yield(key1: 1, key2: 2)
end

something { |key1: key1, key2: key2|  puts "key1:#{key1}, key2:#{key2}" }
# (irb):351: warning: circular argument reference - key1
# (irb):351: warning: circular argument reference - key2
# key1:1, key2:2

As expected says there's a circular reference... but wait a second! key1 and key2 are properly defined!

Ok, so they were defined before, that means, I can get rid of the hash altogether, right?

something { |key1, key2|  puts "key1:#{key1}, key2:#{key2}" }
# key1:{:key1=>1, :key2=>2}, key2:

No, circular reference great! but... the parallel assignment does not work, the first variable get the whole hash.

So I tried cleaning up things a little more:

something { |key1: nil, key2: nil|  puts "key1:#{key1}, key2:#{key2}" }
# key1:1, key2:2

Now it works. But why are those default values needed at all?

What is exactly happening here? Is there a better way of iterating over list of hashes expanding them? Pointers to documentation would also be appreciated.


Solution

  • Now it works. But why are those default values needed at all?

    They aren't, you can just omit the default values:

    something { |key1:, key2:| puts "key1:#{key1}, key2:#{key2}" }
    # key1:1, key2:2