Подтвердить что ты не робот

Передача хеша функции (* args) и ее значение

При использовании идиомы, такой как:

def func(*args)
  ...
end

В чем смысл * args? Популяция этого конкретного вопроса была довольно сложной, и я ничего не мог найти.

Кажется, что все аргументы фактически появляются в args [0], поэтому я нахожу себе защитный код, например:

my_var = args[0].delete(:var_name) if args[0]

Но я уверен, что лучший способ я пропускаю.

4b9b3361

Ответ 1

* - это оператор splat (или звездочка). В контексте метода он задает список аргументов переменной длины. В вашем случае все аргументы, переданные в func, будут помещаться в массив с именем args. Вы также можете указать конкретные аргументы перед аргументом переменной длины следующим образом:

def func2(arg1, arg2, *other_args)
  # ...
end

Скажем, мы называем этот метод:

func2(1, 2, 3, 4, 5)

Если вы проверите arg1, arg2 и other_args в func2 сейчас, вы получите следующие результаты:

def func2(arg1, arg2, *other_args)
  p arg1.inspect       # => 1
  p arg2.inspect       # => 2
  p other_args.inspect # => [3, 4, 5]
end

В вашем случае вы, кажется, передаете хэш в качестве аргумента для вашего func, и в этом случае args[0] будет содержать хэш, как вы наблюдаете.

Ресурсы


Обновление на основе комментариев OP

Если вы хотите передать Hash в качестве аргумента, вы не должны использовать оператор splat. Ruby позволяет вам опустить скобки, в том числе те, которые задают хеш (с оговоркой, продолжают читать) в ваших вызовах метода. Поэтому:

my_func arg1, arg2, :html_arg => value, :html_arg2 => value2

эквивалентно

my_func(arg1, arg2, {:html_arg => value, :html_arg2 => value2})

Когда Ruby видит оператор => в вашем списке аргументов, он знает, что он принимает аргумент как хэш, даже без явного обозначения {...} (обратите внимание, что это применимо только в том случае, если хэш-аргумент является последним!).

Если вы хотите собрать этот хеш, вам не нужно делать ничего особенного (хотя вы, вероятно, захотите указать пустой хеш в качестве значения по умолчанию в определении вашего метода):

def my_func(arg1, arg2, html_args = {})
  # ...
end

Ответ 2

def func(map={})
  x = map.delete(:y)
end