В Ruby мощными операторами обеспечивается гибкость при работе с аргументами в методах или присваиваниями. Два самых ходовых  —  звездочка (*) и двойная звездочка (**). Ими упрощается работа с аргументами именованными и переменной длины.

Оператор-звездочка (*) в Ruby

Малопонятный, на первый взгляд, оператор-звездочка (*) является невероятно мощным и гибким инструментом. Вот принцип его работы.

1. Передача неопределенного количества аргументов методу

Обычно, когда в Ruby определяется метод, явно указывается количество принимаемых им аргументов:

def call_me(var1, var2, var3, var4, var5)
puts "#{var1} #{var2} #{var3} #{var4} #{var5}"
end

call_me(1, 2, 3, 4, 5) # Вывод: "1 2 3 4 5"

А как сделать количество передаваемых аргументов неограниченным? С помощью оператора-звездочки:

def call_me(*vars)
puts vars.join(' ')
end

call_me(1, 2, 3, 4, 5) # Вывод: "1 2 3 4 5"
call_me(1, 2) # Вывод: "1 2"
call_me() # Вывод: ""

В этом примере все передаваемые методу аргументы собираются посредством *vars в массив. Передается любое количество аргументов или ни одного, метод справится с этим.

2. Присваивание более чем одного значения

Оператором-звездочкой переменным присваиваются значения из массива:

a, b, c = [1, 2, 3]
# a = 1, b = 2, c = 3

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

a, b, c = [1, 2, 3, 4]
# a = 1, b = 2, c = 3, «4» удаляется

С помощью оператора-звездочки:

a, b, *c = [1, 2, 3, 4]
# a = 1, b = 2, c = [3, 4]

В этом случае оставшиеся в массиве значения собираются в c. С таким поведением управлять массивами разного размера проще.

Другие варианты присвоения при помощи оператора-звездочки:

a, *b, c = [1, 2, 3, 4]
# a = 1, b = [2, 3], c = 4

*a, b, c = [1, 2, 3, 4, 5, 6]
# a = [1, 2, 3, 4], b = 5, c = 6

Оператор-звездочка очень кстати при работе с массивами разной длины: несколько значений собираются им в одну переменную, в виде массива.

3. Звездочка для разложения массива

Оператором-звездочкой раскладываются массивы, передаваемые методам как аргументы:

def sum(a, b, c)
a + b + c
end

numbers = [1, 2, 3]
puts sum(numbers[0], numbers[1], numbers[2]) # это переписывается в виде:
puts sum(*numbers) # Вывод: 6

В этом случае массив [1, 2, 3] посредством *numbers раскладывается на отдельные аргументы для метода sum.

Оператор  —  двойная звездочка (**) в Ruby

В отличие от оператора-звездочки этот используется специально для именованных аргументов в методах. Такие аргументы передаются в виде пар «ключ-значение» и применяются обычно, когда методу требуются именованные аргументы.

1. Передача именованных аргументов

Вот принцип работы оператора  —  двойной звездочки:

def describe_person(**details)
details.each do |key, value|
puts "#{key.capitalize}: #{value}"
end
end

describe_person(name: "John", age: 30, occupation: "Developer")

Вывод:

Name: John
Age: 30
Occupation: Developer

Все передаваемые методу именованные аргументы собираются посредством **details в хеш. В метод передается любое количество именованных аргументов, они доступны в виде пар «ключ-значение».

2. Объединение хешей при помощи оператора  —  двойной звездочки

Оператором  —  двойной звездочкой также объединяются хеши, особенно при работе с именованными аргументами в вызовах методов:

def display_options(**options)
defaults = { font_size: 12, color: "black" }
options = defaults.merge(options)
puts options
end

display_options(font_size: 18, font_family: "Arial")

Вывод:

{:font_size=>18, :color=>"black", :font_family=>"Arial"}

В этом примере методом display_options набор параметров по умолчанию объединяется с любыми именованными аргументами, переданными пользователем. Именованные аргументы собираются в хеш посредством **options, поэтому легко обрабатываются.

Заключение

  • Оператор-звездочка (*)  —  мощный инструмент Ruby для работы с неограниченным количеством аргументов или присвоения сразу нескольких значений. Аргументы им собираются в массивы, а массивы раскладываются при передаче в методы.
  • Оператор  —  двойная звездочка (**) аналогичен, но применяется специально для обработки именованных аргументов. Именованные аргументы собираются им в хеш и используются обычно, когда требуются методу.

Обоими операторами коду Ruby добавляются гибкость и удобство восприятия, благодаря чему упрощается работа с динамическими аргументами и соответствующими параметрами.

Читайте также:

Читайте нас в Telegram, VK и Дзен


Перевод статьи Kabir Pathak: Ruby splat(*) and double splat(**) operators

Предыдущая статьяРеализация «бесконечного» пейджера в Jetpack Compose
Следующая статья10 рекомендаций по Apache Airflow для дата-инженеров