Помимо конструкторов, таких как range и spread, есть и другой способ создания новых колец - манипулирование существующими кольцами.
Чтобы исследовать это, возьмём простое кольцо:
(ring 10, 20, 30, 40, 50)
Что, если мы хотим перевернуть его задом наперёд? Тогда мы используем связанный метод .reverse, который разворачивает кольцо в обратную сторону:
(ring 10, 20, 30, 40, 50).reverse #=> (ring 50, 40, 30, 20, 10)
Так, а что, если мы захотим получить первые три элемента кольца?
(ring 10, 20, 30, 40, 50).take(3) #=> (ring 10, 20, 30)
И, наконец, что, если мы захотим перемешать элементы кольца?
(ring 10, 20, 30, 40, 50).shuffle #=> (ring 40, 30, 10, 50, 20)
Это очень мощный способ создания новых колец. Однако, реальная мощь приходит, когда вы связываете несколько методов вместе.
Как на счёт перемешать кольцо, отбросить 1 элемент, а затем получить первые 3 элемента?
Давайте сделаем это в несколько этапов:
(ring 10, 20, 30, 40, 50) - наше исходное кольцо
(ring 10, 20, 30, 40, 50).shuffle - перемешиваем - (ring 40, 30, 10, 50, 20)
(ring 10, 20, 30, 40, 50).shuffle.drop(1) - отбрасываем 1 элемент - (ring 30, 10, 50, 20)
(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3) - берём 3 первых элемента - (ring 30, 10, 50)
Как вы видете, можно создавать длинные связки из этих методов просто склеивая их вместе. Мы можем комбинировать их в любом порядке, в каком захотим, создавая чрезвычайно богатый и мощный способ генерации новых колец из существующих.
Наши кольца обладают одним очень важным свойством. Оно заключается в том, что связанные методы, описанные в этом разделе не изменяют кольца, они возвращают новые кольца. Это значит, что вы можете разделять кольцо между потоками выполнения и использовать разные методы в разных потоках, зная, что не повлияете на другой поток, использующий то же самое кольцо.
Вот список доступных для вас связанных методов:
.reverse - возвращает отсортированную в обратном порядке версию кольца
.sort - возвращает отсортированную версию кольца
.shuffle - возвращает отсортированную в случайном порядке версию кольца
.pick(3) - returns a ring with the results of calling .choose 3 times
.pick - similar to .pick(3) only the size defaults to the same as the original ring
.take(5) - возвращает кольцо, содержащее первые 5 элементов исходного кольца
.drop(3) - возвращает кольцо, содержащее все элементы исходного кольца, кроме первых 3 элементов
.butlast - возвращает новое кольцо с отсутствующим последним элементом
.drop_last(3) - возвращает новое кольцо с отсутствующими 3 последними элементами
.take_last(6)- возвращает кольцо, содержащее последние 6 элементов исходного кольца
.stretch(2) - повторяет каждый элемент кольца дважды
.repeat(3) - повторяет всё кольцо 3 раза
.mirror - добавляет кольцо к перевёрнутой версии себя
.reflect - то же, что и .mirror, но не дублирует средний элемент
.scale(2) - returns a new ring with all elements multiplied by 2 (assumes ring contains numbers only)
Конечно, связанные методы, принимающие числовые аргументы, могут принимать и другие числа! Так что не стесняйтесь вызывать .drop(5) вместо .drop(3), если вы хотите отбросить первые 5 элементов кольца.