Project

General

Profile

Bug #16421

public_send with empty keyword arguments (Ruby version < 2.7)

Added by zverok (Victor Shepelev) 8 months ago. Updated 8 months ago.

Status:
Closed
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:96234]

Description

Probably it is something that I've just missed, so it is more a question than bug report.
In Ruby < 2.7, I'd implement "delegate everything" method as such:


def delegate(name, *args, &block)
  @something.public_send(name, *args, &block)
end

Now, while updating one of my gems to Ruby 2.7, I receive a warning (if SOME of the delegated methods accept keyword args):

class A
  def simple_method(arg)
    p arg
  end

  def kwargs_method(arg, kwarg:)
    p [arg, kwarg]
  end

  def delegate(name, *args, &block)
    public_send(name, *args, &block)
  end
end

A.new.delegate(:kwargs_method, 1, kwarg: 2) # warning: The last argument is used as the keyword parameter

OK, that's understandable!
Now, I am trying to rewrite kode to work with both 2.6 and 2.7:

class A
  def simple_method(arg)
    p arg
  end

  def kwargs_method(arg, kwarg:)
    p [arg, kwarg]
  end

  def delegate(name, *args, **kwargs, &block)
    public_send(name, *args, **kwargs, &block)
  end
end

A.new.delegate(:kwargs_method, 1, kwarg: 2)
A.new.delegate(:simple_method, 1)

It warks as expected under 2.7, but under 2.6, the last line throws:

tmp/delegate.rb:2:in `simple_method': wrong number of arguments (given 2, expected 1) (ArgumentError)

Is it something obvious that I am missing (I tried to search through the tracker, but can't detect related issues...). It there something I can do to have code working in both 2.6 and 2.7 without falling back to ruby_2keywords or if RUBY_VERSION < '2.7' (or checking for kwargs in if method(name).parameters)?..

Updated by jeremyevans0 (Jeremy Evans) 8 months ago

  • Status changed from Open to Closed

You should use ruby2_keywords:

  def delegate(name, *args, &block)
    public_send(name, *args, &block)
  end
  ruby2_keywords :delegate if respond_to?(:ruby2_keywords, true)

Then things will work correctly. This type of code is the reason that ruby2_keywords was introduced.

Also available in: Atom PDF