Bug #16421
closedpublic_send with empty keyword arguments (Ruby version < 2.7)
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) over 5 years 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.
Updated by zverok (Victor Shepelev) over 5 years ago
@jeremyevans0 (Jeremy Evans) yeah, thanks, I see now.