ruby 2.7.3p183
Here is the situation, this method:
def send_request(url, payload = {}, internal_proxy: true)
...
and this call
send_request('random_address', { foo: :bar })
Returns me:
Traceback (most recent call last):
5: from C:/Ruby27-x64/bin/irb.cmd:31:in `<main>'
4: from C:/Ruby27-x64/bin/irb.cmd:31:in `load'
3: from C:/Ruby27-x64/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
2: from (irb):4
1: from (irb):1:in `send_request'
ArgumentError (unknown keyword: :foo)
I understand that it is trying to match the optional parameters, but why? shoudn't 'payload' variable receive the parameter?, I tried to search for an explanation, but I can't seem to find any
I used to use internal_proxy variable just like payload;
def send_request(url, payload = {}, internal_proxy = true)
but rubocop warns me;
Use keyword arguments when defining method with boolean argument.
(convention:Style/OptionalBooleanParameter)
Does hash on the first not optional parameter always count as the keyword argument? If so, how can I get the expected behaviour I mentioned above? (unless is a bad practice for some reason)
Is this a bug, or is there a reason for this??
In Ruby < 3.0, if the last argument is a hash, and the method being called accepts keyword arguments, then it is always converted to keyword arguments.
Ruby 3.0 fixes this.
You should upgrade to Ruby 3.0 if you can, or else think of a different API.
A possible solution for your problem is to change the order of your parameters as follow:
def send_request(url, internal_proxy: true, **payload)
p payload
p 'fooo'
end
send_request('asd', {foo: :bar})
send_request('asd')
The above code should perform the behavior you are looking for. Also, introducing the double splat (**) collects all the extra named keywords as a hash parameter. The first call will print the hash {foo: :bar} and the second call will print an empty hash {} you can try the above snippet here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With