[Перевод] Несколько полезных ruby-трюков, которые (возможно) улучшат ваш код
Скучая в эту дождливую праздничную погоду, наткнулся на занимательную статейку в блоге с говорящим названием Samurails, в которой описываются некоторые интересные ruby трюки, которые наверняка будут интересны новичкам. Итак, приступимСоздаем хэш из массиваПроще простого. Ставим команду Hash перед любым массивом и получаем готовые пары ключ/значение: Hash['key1', 'value1', 'key2', 'value2']
# => {«key1»=>«value1», «key2»=>«value2»} Lambda как → Возможность проставлять лямбду при помощи → появилась сравнительно недавно, будем пробовать: a = → { 1 + 1 } a.call # => 2
a = → (v) { v + 1 } a.call (2) # => 3 Двойная звездочка (**) Как вам такой метод: def my_method (a, *b, **c) return a, b, c end
, а — это обычный аргумент. *b примет все аргументы после «a» и выведет их массивом, а вот **c принимет только параметры в формате ключ/значение, после чего отдаст нам хэш. Посмотрим примеры: Один аргумент:
my_method (1) # => [1, [], {}]
Набор аргументов: my_method (1, 2, 3, 4) # => [1, [2, 3, 4], {}]
Набор аргументов + пары ключ/значение my_method (1, 2, 3, 4, a: 1, b: 2) # => [1, [2, 3, 4], {: a=>1, : b=>2}]
По-моему круто.Обращаемся с переменной и с массивом одинаково Иногда (лишь иногда) у вас может возникнуть желание запустить на объекте какой-либо метод без проверки его типа. То бишь обращаться с массивом так же как, скажем, с обычной переменной. В таких случаях можно пойти двумя путями — использовать [*something] или Array (something).Давайте попробуем. Назначим две переменные: число и массив чисел
stuff = 1 stuff_arr = [1, 2, 3]
Используя [*] мы можем одинаково успешно итерировать по обеим переменным: [*stuff].each { |s| s } [*stuff_arr].each { |s| s }
Идентично: Array (stuff).each { |s| s } Array (stuff_arr).each { |s| s }
||= Отличный ключ к сокращению количества строк нашего кода — использование ||=
Важно понять, что этот оператор работает так:
a || a = b # Верно А не так:
a = a || b # Неверно! Этот оператор прекрасно подходит для выполнения математических операций:
def total @total ||= (1…100000000).to_a.inject (:+) end Теперь мы можем использовать total в других методах, но посчитается он только один раз, что отразится на производительности нашего приложения.
Обязательные хэш-параметры Совсем новая фича вторых рубей. Вместо того, чтобы определять метод с указанием хэша в качестве принимаемого аргумента:
def my_method ({}) end
теперь мы можем четко определить ключи, которые мы ждем на входе. Более того, мы можем определить их значения! В данном примере a и b являются обязательными ключами:
def my_method (a:, b:, c: 'default') return a, b, c end
Можем попробовать отправить в метод только «а» и нарваться на ошибку: my_method (a: 1) # => ArgumentError: missing keyword: b
Так как мы указали значение по умолчанию для «с», нам достаточно предоставить методу ключи «а» и «b»: my_method (a: 1, b: 2) # => [1, 2, «default»]
Или же можем отправить все три: my_method (a: 1, b: 2, c: 3) # => [1, 2, 3]
Можем быть более лаконичны: hash = { a: 1, b: 2, c: 3 } my_method (hash) # => [1, 2, 3]
Генерируем алфавит или цепочку чисел при помощи range Трюк достаточно старый, но вдруг кто-то не в курсе. ('a'…'z').to_a # => [«a», «b», «c», «d», «e», «f», «g», «h», «i», «j», «k», «l», «m», «n», «o», «p», «q», «r», «s», «t», «u», «v», «w», «x», «y», «z»]
(1…10).to_a # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Tap Tap — это отличный метод, способный улучшить читаемость нашего кода. Допустим, у нас есть класс: class User attr_accessor: a, : b, : c end
Теперь, допустим, нам захотелось создать нового пользователя, с аттрибутами. Можно сделать это так: def my_method o = User.new o.a = 1 o.b = 2 o.c = 3 o end
А можно использовать tap: def my_method User.new.tap do |o| o.a = 1 o.b = 2 o.c = 3 end end