Відповіді:
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}]
Це оператор подвійної заставки, який доступний з 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 код набирає досить багато лаконічності.
Крім того, ви можете використовувати його на стороні виклику, як це:
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}
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 масиви.