Несколько полезных 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 

ссылка на оригинал статьи http://habrahabr.ru/post/257151/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *