В Ruby много методов, которые применяются не очень часто, и о тех случаях, в которых они задействуются, многие просто не знают, потому что никогда этими методами не пользовались.
Предлагаем вашему вниманию список таких малоизвестных методов Ruby. Так что, когда вам захочется узнать, есть ли в Ruby метод, который пригодится в вашей программе, или когда на глаза попадется какой-то незнакомый метод, у вас под рукой уже будет готовый список со всей необходимой информацией.
Итак, перейдем к списку.
1. Манипуляции с аргументами
1) Деструктурирование аргументов:
def print_from_array((a1,a2))
print first: a1, second: a2
end
print_from_array(['output1', 'output2'])
=> {first: 'output1'}, {second: 'output2'}
Когда при определении метода добавляется вторая пара скобок вокруг аргументов, например так => method((a1,a2))
, происходит деструктурирование массива, передаваемого в этот метод в качестве аргумента. Смотрите: в строке 5, несмотря на то, что в массив print_from_array
передается только один аргумент, метод print_from_array
воспринимает a1
и a2
как элементы этого массива и выводит отдельные элементы. (Обратите внимание: с хешем такое не проходит. В примере это def print_from_array({a1,a2})
.)
В обратном порядке, когда метод определяется вот так:
def print_from_array((a1,a2))
print first: a1, second: a2, third: a3
end
print_from_array(['output1', 'output2', 'output3'])
=> NameError (undefined local variable or method `a3' for main:Object)
возникает ошибка даже при передаче массива из трех элементов.
2) Преобразование аргументов в массив:
def convert_args_to_array(*args)
print args
end
convert_args_to_array("string1", "string2", "string3")
=> ["string1", "string2", "string3"]
Здесь происходит преобразование в массив любых аргументов, передаваемых в convert_args_to_array
, даже когда они передаются как что-то другое.
А еще выполняется такое преобразование:
def convert_some_args_to_array(arg1, *args)
print arg1, args
end
convert_some_args_to_array("string1", "string2", "string3")
=> string1 ["string2", "string3"]
Первый аргумент отделяется, после чего остальные преобразуются в массив.
2. Методы массивов
1) Оператор пересечения « &
»:
array1 = [1,2,3,4,5,6,7,8,9]
array2 = [1,2,3,4,'a','b','c']
array3 = ['a','b','c','d','e']
array1 & array2 => [1,2,3,4]
array2 & array3 => ['a','b','c']
array1 & array3 => []
В случае когда берутся два массива с целью найти их общие элементы (пересечение), используется оператор &
. Возвращается новый массив с элементами, которые есть в обоих этих массивах.
2) Разностный оператор « — »
:
array1 = [1,2,3,4,5,6,7,8,9]
array2 = [1,2,3,4,'a','b','c']
array3 = ['a','b','c','d','e']
array1 - array2 => [5,6,7,8,9]
array2 - array1 => ['a','b','c']
array2 - array3 => [1,2,3,4]
array3 - array2 => ['d','e']
Когда надо определить разницу между двумя массивами, используется разностный оператор. В этом случае возвращается новый массив с элементами, которые есть в первом массиве и которых нет во втором.
3) Метод «rotate
»:
array = [1,2,3,4,5]
array.rotate => [2,3,4,5,1]
С помощью этого метода весь массив просто поворачивается таким образом, что первый элемент теперь становится последним.
И есть ещё
4) метод «shuffle
»:
array = [1,2,3,4,5]
array.shuffle => [5, 4, 2, 1, 3]
array.shuffle => [3, 4, 5, 1, 2]
array.shuffle => [5, 1, 3, 2, 4]
из которого возвращается новый массив со случайно упорядоченными элементами. Элементы перетасовываются каждый раз заново, так что массив возвращается уже с другой последовательностью элементов. (Подходит для игр и т. п.)
3. Proc.new (или proc
) и лямбда (->{блок кода})
Это совсем малоизвестная концепция, однако является очень важной частью Ruby (и многих других языков тоже).
Вот что сказано о ней на ruby-doc.org:
Объект Proc
представляет собой инкапсуляцию блока кода, который хранится в локальной переменной, передается методу или другому Proc, и вызывается. Proc — это важнейшее понятие в Ruby и сердцевина его возможностей, связанных с функциональным программированием.
Чувствую, что должным образом освятить эту тему не получится, поэтому просто оставлю пару ссылок для тех, кому нужна дополнительная информация.
Proc — это фактически блок кода, который сохраняется в переменной и потом вызывается с помощью .call
. Выглядит он обычно так:
add_one = proc {|number| number + 1}
add_one.call(5) => 6
Вам должен быть знаком этот синтаксис по другим методам, таким как .map
или .filter
. Но на самом деле Proc (использующийся как синоним блока кода) задействуют для того, чтобы указать на логику, выполняемую на каждой итерации.
Дальнейший материал неплохо бы читать, предварительно ознакомившись с документацией по Ruby: ruby-docs или rubyguides.com.
По этой теме следует сказать несколько слов об операторе Proc &
. В отличие от оператора пересечения, о котором упоминалось ранее в этой статье, при использовании в качестве аргумента для метода вызывается оператор деконструкции блока и указывает методу, что передаваемый аргумент — это Proc (блок кода) и должен таковым и считаться.
Вот его типичный синтаксис:
p = proc {|x, y| x + y }
[[1, 2], [3,4]].map(&p) #=> [3, 7]
Обратите внимание: это обычный метод .map
и вместо того ,чтобы определять блок кода после map
, здесь на первой строке определяется proc
и дальше с помощью &
передается в map
. В map
сообщается, что это блок, который map
должен использовать для логики, выполняемой на каждой итерации.
Заключение
Вот и все. Мы разобрали несколько малоизвестных, но полезных и интригующих методов и концепций. Хотел бы я узнать о некоторых из них раньше, потому что они пригодились бы мне в тех ситуациях, когда не получалось найти правильный метод для той или иной задачи. И хорошо, что они есть у нас сейчас. А некоторые из них мне показались просто интересными, и теперь, когда они понадобятся, у вас под рукой уже будет готовый список со всеми методами.
Читайте также:
- Создание простого веб-скрейпера на Ruby
- Парсинг HTML из строки на Ruby On Rails
- Подробный разбор методов Ruby
Читайте нас в Telegram, VK и Яндекс.Дзен
Перевод статьи Yisrael Gurkow: A compendium of obscure Ruby methods (or maybe just a couple methods/concepts that I didn’t know before…)