Що робить оператор подвійного * (splat)


214

Ви бачили функцію, оголошену таким?

def foo a, **b
  ...
end

Я розумію, що сингл *- оператор splat. Що **означає?

Відповіді:


373

Ruby 2.0 представив аргументи ключових слів і **діє як *, але для аргументів ключових слів. Він повертає Hash з парами ключ / значення.

Для цього коду:

def foo(a, *b, **c)
  [a, b, c]
end

Ось демонстрація:

> foo 10
=> [10, [], {}]
> foo 10, 20, 30
=> [10, [20, 30], {}]
> foo 10, 20, 30, d: 40, e: 50
=> [10, [20, 30], {:d=>40, :e=>50}]
> foo 10, d: 40, e: 50
=> [10, [], {:d=>40, :e=>50}]

44
Це прекрасно відповідає на питання, але у мене було незначне доповнення. Так само, як оператор splat може бути використаний у масиві, який ви проходите, подвійний splat може бути використаний на хешах. Якщо opts = {d: 40, e: 50}, то foo 10, opts, f: 60призначить {f: 60}до c, в той час як foo 10, **opts, f: 60призначатиме {d: 40, e: 50, f: 60}. Щоб досягти другого ефекту, раніше ви мали б mergeчітко d масиви.
brymck

Я вважаю, що це корисно для встановлення необов'язкових хеш-параметрів для методу
bigpotato

Напевно, варто зауважити, що якщо змішувати ключові слова-аргументи з ключовими словами splat, ключове слово splat має прийти після аргументів ключового слова.
MrMesees

43

Це оператор подвійної заставки, який доступний з Ruby 2.0.

Він фіксує всі аргументи ключових слів (що також може бути простим хешем, який був ідіоматичним способом емуляції аргументів ключових слів до того, як вони стали частиною мови Ruby)

def my_method(**options)
  puts options.inspect
end

my_method(key: "value")

Вищевказаний код друкується {key:value}на консолі.

Так само, як оператор одиночного інструментарію фіксує всі регулярні аргументи, але замість масиву ви отримуєте хеш .

Приклад із реального життя:

Наприклад, у Rails cycleметод виглядає приблизно так:

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end

Цей метод можна назвати так: cycle("red", "green", "blue", name: "colors").

Це досить поширена закономірність: ви приймаєте список аргументів, і останній - хеш параметрів, який можна витягнути, наприклад, за допомогою ActiveSupport's extract_options!.

У Ruby 2.0 ви можете спростити такі методи:

def cycle(first_value, *values, **options)
  # Same code as above without further changes!
end

Безумовно, це лише незначне поліпшення, якщо ви вже використовуєте ActiveSupport, але для простого Ruby код набирає досить багато лаконічності.


20

Крім того, ви можете використовувати його на стороні виклику, як це:

def foo(opts); p opts end
bar = {a:1, b:2}

foo(bar, c: 3)
=> ArgumentError: wrong number of arguments (given 2, expected 1)

foo(**bar, c: 3)
=> {:a=>1, :b=>2, :c=>3}

5
Нічого собі, подвійний шлейф аналогічний оператору розповсюдження об'єктів ES6.
mpoisot

1
Дякую, це підтвердження, яке я шукав.
Qortex
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.