Passing empty hash through double sign in ruby

The idea is similar to what you would do with a decorator in python, I don't know what arguments the method uses, so I pass * args, ** kwargs as a general case

The problem occurs when I want to pass an empty hash as kwargs to a method that takes no arguments

def my_method
  'I have run correctly'
end

args = []
kwargs = {}

my_method *args, **kwargs
=> ArgumentError: wrong number of arguments (given 1, expected 0)

      

Interestingly, only the kwargs variable seems to be a problem as:

my_method *args, **{}
=> 'I have run correctly'

      

If you can suggest a way to actually pass a method object as a parameter to a function, that would be fine too.

+3


source to share


1 answer


You cannot pass an arbitrary number of arguments to a ruby ​​method without declaring it in the method definition. Passing only *args

works because since the args arguments are empty, it is basically like you are not passing arguments to the methods, which is what my_method expects. With, kwargs

you pass an empty hash as an argument. Since the method is declared with no arguments, this raises an error.

In general, the way to do it in ruby ​​would be something like this:

def my_method(*args, **kwargs)
  'I have run correctly'
end

      

If a ruby ​​method can take an indefinite number of arguments or keyword arguments, it must be explicit in the method definition.

More often than not, you will see idioms like this:

def my_method(arg, opts={})
  # do something
end

# Invoke the method like this:
# args == ['argument', 'another argument']
# opts == {opt1: 'val1', opt2: 'val2'}
my_method('some argument', opt1: 'val1', opt2: 'val2')

      




Regarding your observation of my_method *args, **kwargs

acting differently than my_method *args, **{}

... I will first say that if your motivation is primarily in learning Ruby, then I would re-emphasize my point that kwargs are not usually used in Ruby. at least not in the way they are used in Python.

And after that I will say that it is very strange.

I noticed that:

[**kwargs] # => [{}]
[**{}] # => []
# And even more interesting:
[**{}.itself] # => [{}]

      

So, I was right in saying that when the **kwargs

interpreter is complaining, because you are passing an empty hash to a method that does not expect any arguments. But why this is different from **{}

I am not sure. I'm digging right now, but my current suspicion is honest that this is an accident of the translator. There is no reason why they should be evaluated differently just because one of them is being assigned to a variable ...

What's more, the adoption of the double splat operator is not very widespread, mainly due to a preference for the opts={}

idiom described above . In addition, this is not an accidental case that many may come across in practice. The programmer would have to explicitly pass an empty hash to such a method when they could (regardless of whether kwargs or opts) just omit the argument. So yeah ... I think it might be the translator's failure.

+2


source







All Articles