0

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.

estani
  • 24,254
  • 2
  • 93
  • 76

1 Answers1

2

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
Stefan
  • 109,145
  • 14
  • 143
  • 218
  • wow, I didn't now this. This doesn't seem to work with the arrow style hash. Do you have a reference to some documentation where this is described? – estani Apr 14 '20 at 11:05
  • Keyword arguments and hashes have a similar syntax, but are different things. See [Keyword Arguments](https://ruby-doc.org/core-2.7.1/doc/syntax/methods_rdoc.html#label-Keyword+Arguments) and [Hash to Keyword Arguments Conversion](https://ruby-doc.org/core-2.7.1/doc/syntax/calling_methods_rdoc.html#label-Hash+to+Keyword+Arguments+Conversion) – Stefan Apr 14 '20 at 11:09
  • Note: `something { |key1: 3, key2: 4| puts "key1:#{key1}, key2:#{key2}" } #=> key1:1, key2:2`. – Cary Swoveland Apr 14 '20 at 18:08