New 2.7/3.0 keyword argument pain point

Hi. Not rails-related, but I’ve stumbled across this thread, and since I’m in the middle of quite a bit of pain related to these changes, I thought I might want to share.

I thought I was being a good Ruby citizen, and slowly migrating my code to using keyword arguments, double splat and all that. I (fortunately for me) am not keeping very long backward compatibility across ruby versions, so I can do this type of things.

I basically thought I was all set. A few days of fixing the (very welcome) warnings and that’s it. Boy was I wrong.

I ended up hitting the decision of allowing arbitrary keyword arguments in 2.7, at the same time than the other changes - my (rightfully rejected) bug report is here.

To be honest, I felt very cheated. I thought I was doing the right thing with a slow upgrade, and keyword arguments have rejected anything that’s not a Symbol since day 1. So, I (stupidly) assumed that it would stay that way at least until the “real” keyword args arrive (a.k.a. after 3.0). Now, were something like that happen again, I’d basically go the route of wait and change stuff only when strictly required.

It turns out that the “user-facing” API of my library (a robotic framework) is a DSL, and some methods are given both a mapping of strings to strings and keyword arguments. But then, I thought I’ll be fine (because there’s no way they can break that, strings can’t go in kw args). However, what was working before:

def provides(h = {}, **kw); end
provides "some" => "strings", as: "name"

now resolves everything into the keyword splat. I’m scared of even changing things now, since adding a keyword splat will break code. If I would change the following signature:

def m(mapping = {}, as: nil); end

into one that has a keyword splat - for instance to forward arbitrary arguments to another method -

def m(mapping = {}, as: nil, **kw); end

then what was going into mapping now goes into kw

This change IMO makes no sense from a backward compatibility perspective. It is a change that could definitely have waited for 3.1 after the real keyword arguments are here and here to stay, where everyone properly separated hashes from keywords. I’ve been through the 1.9 transition, and I feel like that.

Don’t get me wrong, I like the idea of using 3.0 as a way to finally fix the kw args mess, and 2.7 as a stepping stone to there. And I am biting the bullet and trying to get this to work.

But this is not that. This is a backward-compatibility-breaking change that was there not to clean up in the way to 3.0, but to add new functionality that was not there before.

As for the warnings, we would ideally need a way to disable them per-package. Users of rails or other libraries/frameworks shouldn’t have to care that the framework needs updating.

Finally, last but not least, Ubuntu 20.04 shipped with Ruby 2.7. This is going to be a lot of pain for Ruby developers on Ubuntu, and I believe will fuel the dislike of Ruby for that platform’s users.

1 Like