Ruby 3.0 - Procs accepting a single rest argument and keyword arguments are no longer subject to autosplatting


This blog post discusses the inconsistent behavior of procs regarding autsplatting when rest argument and keyword arguments are present.

Before

The behavior for autosplatting was inconsistent when input was passed to procs with rest argument and keyword arguments vs when the same input was passed to procs with only rest argument.

proc_with_only_rest_argument = Proc.new { |*rest| [rest] }

proc_with_only_rest_argument.call(["content"])
 #=> [[["content"]]]

proc_with_rest_and_kwargs = Proc.new { |*rest, **kwargs| [rest] }

proc_with_rest_and_kwargs.call(["content"])
#=> [["content"]]

As we can see in the above example, for the same input both procs behaved differently. The output is different in both the cases. proc_with_rest_and_kwargs did autosplatting, and hence [] was not wrapped over the input [content].

After

With the recent changes merged to master, the autosplatting behavior is fixed as demonstrated below:

proc_with_only_rest_argument = Proc.new { |*rest| [rest] }

proc_with_only_rest_argument.call(["content"])
 #=> [[["content"]]]

proc_with_rest_and_kwargs = Proc.new { |*rest, **kwargs| [rest] }

proc_with_rest_and_kwargs.call(["content"])

#=> [[["content"]]]

As we can see in the above example, the behavior is made consistent.