Ruby - метод расширения с помощью super с помощью знака

В электронной книге Комплексный курс программирования на Ruby описан случай, когда метод дочернего класса расширяет метод родительского. Я не совсем понимаю, как это работает:

class Parent
  def initialize(foo:, bar:)
   @foo = foo
   @bar = bar
  end
end

class Child < Parent
  def initialize(buzz:,**args)
   super(**args)
   @buzz = buzz
  end
end

Я не могу полностью понять, почему мы используем знак здесь - **args. Здесь def initialize(buzz:,**args) мы просто говорим initialize принять неизвестное количество аргументов ключ-значение, верно? Но что именно это означает super(**args). Чтобы сказать методу, чтобы он брал эти аргументы ключ-значение из метода суперкласса? Почему бы не просто так:

class Child < Parent
  def initialize(buzz:)
   super
   @buzz = buzz
  end
end

В конце концов, super говорит о расширении метода тем, что есть в родительском объекте, так зачем нужны эти splat-аргументы?


person Julius    schedule 31.03.2017    source источник
comment
Вы попробовали свое решение? Вы получите сообщение об ошибке, которое должно точно сказать вам, зачем нужны аргументы splat.   -  person meagar    schedule 31.03.2017


Ответы (1)


**args в списке параметров просто означает "получить все дополнительные аргументы ключевого слова и поместить их в хэш с именем args".

И наоборот, **args при вызове метода делает обратное: "получает этот хэш с именем args и передает аргументы ключевого слова с соответствующими именами и значениями из этого хеша".


super без аргументов попытается передать все аргументы, полученные дочерним методом. Следовательно, если у вас есть лишнее, чего родитель не ожидал, вы получите ArgumentError.

В вашем примере родитель ожидает только foo: и bar:, а ребенок также имеет buzz:.

person ndnenkov    schedule 31.03.2017