Bug #16111


Combining default positional and keyword arguments is resulting in a `to_hash` method call

Added by mtelford (Michael Telford) over 3 years ago. Updated over 3 years ago.

Target version:
ruby -v:


Combining default positional and keyword arguments is resulting in a to_hash method call when I don't believe it should be. It's affecting some code I am writing. The full details of the behaviour I'm describing can be seen in the attached script.

I would like to know why the method to_hash is being called (only in certain circumstances) and if this is a bug to be fixed or desired behaviour (and why?).

Thank in advance!


ruby-bug.rb (1.44 KB) ruby-bug.rb mtelford (Michael Telford), 08/19/2019 05:46 AM

Updated by mame (Yusuke Endoh) over 3 years ago

I would like to know why the method to_hash is being called

A method call that accepts keywords checks if the last argument is a Hash or not. The check includes attempting to convert it by using to_hash. This is the behavior you are seeing.

I agree that it is very strange. It is elegantly solved if we can separate positional and keyword arguments completely (#14183), but the separation seems to be difficult because the incompatibility is painful.

Updated by mtelford (Michael Telford) over 3 years ago

Ok, thanks for the reply. That now makes more sense. I understand why the last positional argument is type-checked but surely trying to convert it using param#to_hash is a step too far? Doing so basically means that the last positional argument cannot respond_to? :to_hash, as in my case. It's not ideal as my problem still exists.

Updated by shevegen (Robert A. Heiler) over 3 years ago

I think that either way, resolving it may not be trivial/simple right now; if you
look at mame's linked in issue above at #14183, it mentions 19 (somewhat) related
issues concerning keyword arguments. Jeremy also pointed out some bugs prior to
this, and if I remember correctly, matz spoke about the somewhat confusing situation
in a presentation a while ago. This may need to be given some time, for the time
being, but the ruby core team is most likely aware of the situation.

I personally have avoided keyword arguments so far (but unrelated to the issues
mentioned in the issue trackers; I mostly stick to oldschool hashes. Perhaps
this may also be somewhat of a "historic" nature, in that hash-behaviour
came first (the old pickaxe mentioned that, e. g. you could drop the {}
syntax for the last arguments in a method if it was a hash), and at a later
time keyword arguments were added.

If I remember correctly then matz has also mention that the situation with
keyword arguments may be one of the very very few incompatibilities for
ruby 3.0 (perhaps), so I guess it is not out of the question to see a
change in behaviour in this regard. As mame has pointed out, one of the
biggest concern, if not the biggest, is the incompatibility issue.

Updated by mtelford (Michael Telford) over 3 years ago

Ok, the situation with keyword parameters is now making more sense, despite not being ideal. Since ruby 3 should implement a fix (backwards compatible or not) I am happy for this issue to be closed.

Thanks to those who commented to bring me up to speed :-)

Actions #5

Updated by jeremyevans0 (Jeremy Evans) over 3 years ago

  • Status changed from Open to Closed

Also available in: Atom PDF