Передача пустого хеша через двойной знак в рубине

Идея похожа на то, что вы сделали бы с декоратором в python, я не знаю, какие аргументы использует метод, поэтому я передаю *args, **kwargs в общем случае

Проблема возникает, когда я хочу передать пустой хеш как kwargs методу, который не принимает аргументов

def my_method
  'I have run correctly'
end

args = []
kwargs = {}

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

Интересно, что только переменная kwargs кажется проблемой, так как:

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

Если вы можете предложить способ фактической передачи объекта метода в качестве параметра функции, это также было бы идеально.

1 ответ

Вы не можете передать произвольное количество аргументов в метод ruby, не объявив его в определении метода. Проходя просто *args работает, потому что * args пусто, это в основном так, как будто вы не передаете аргументы методам, чего и ожидает my_method. С kwargs, вы передаете пустой хеш в качестве аргумента. Так как метод объявлен без аргументов, возникает ошибка.

В общем случае способ сделать это в ruby ​​будет примерно таким:

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

Если метод ruby ​​может принимать неопределенное количество аргументов или аргументов ключевого слова, он должен быть явным в определении метода.

Однако чаще вы увидите такие идиомы:

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')

Что касается вашего наблюдения о my_method *args, **kwargs действуя иначе, чем my_method *args, **{}... Сначала я скажу, что если ваша мотивация в первую очередь связана с изучением Ruby, то я бы еще раз подчеркнул свою мысль о том, что kwargs обычно не используются в Ruby, по крайней мере, не так, как они используются в Python.

И после этого я скажу, что это очень странно.

Я замечаю, что:

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

Так что я правильно сказал, что **kwargsинтерпретатор жалуется, потому что вы передаете пустой хэш методу, который не ожидает никаких аргументов. Но относительно того, почему это отличается от **{}, Я не уверен. Я копаюсь сейчас, но мое нынешнее подозрение честно, что это случайность переводчика. Нет причин, по которым они должны оцениваться по-разному только потому, что один из двух назначен переменной...

Более того, использование оператора двойных сплатов не очень распространено, в основном из-за предпочтения opts={} идиома описанная выше. Также это не тот случай использования, с которым многие столкнутся на практике. Программист должен был бы явно передать пустой хэш такому методу, когда они могут (независимо от того, kwargs или опции) просто пропустить аргумент. Так что да... Я думаю, что это может быть случайностью переводчика.

Другие вопросы по тегам