Ruby/Идеология: различия между версиями

Содержимое удалено Содержимое добавлено
Строка 148:
К чему я все это рассказываю? Дело в том, что на тот момент я задался вопросом: "действительно ли существуют ситуации, в которых без условного оператора невозможно обойтись?" Есть предположение, что высокоуровневые языки способны свести к минимуму не только использования циклов (в Ruby целесообразней использовать итераторы), но и условных операторов.
 
Для начала, немного теории. В Ruby (а также в Perl) существует метод <code><=></code>, широко применяемый в различных итераторах (<code>sort</code>, <code>max</code>, <code>min</code> и так далее.). По сути, он включает в себя всевозможные операции сравнения (<code><</code>, <code>></code>, <code>>=</code>, <code><=</code>, <code>==</code> и <code>!=</code>) и может замечательно их заменять. Работа этого метода заключается в том, что он возвращает целое число (-1, 0 или 1), в зависимости от результата сравнения. Пример:
 
<source lang=ruby>3 <=> 5 #-> -1
5 <=> 3 #-> 1
3 <=> 3 #-> 0
5 <=> 5 #-> 0</source>
 
Как видно из примера, в случае, если левый агрумент меньше правого, то метод <code><=></code> возвращает -1, если больше, то 1, а если они равны, то 0. Именно это свойство метода <code><=></code> я и собираюсь использовать.
Строка 159:
Но для "эквивалентной замены" условного оператора этого недостаточно. Требуется что-то еще... Это что-то называется "возможность отрицательной индексации в массивах", то есть в Ruby массивы обладают возможностью индексировать свои элементы не только с 0 до N-1, но и с -N до -1, где N — размер массива. Последний элемент будет иметь индекс -1, предпоследний -2 и так далее. Причем, отрицательная индексация уже включена и для ее применения никаких дополнительных действий не требуется. Пример:
 
<source lang=ruby>maccuBArray = [1, 2, 3, 4, 5]
Array[0] #-> 1
Array[-5] #-> 1
Строка 167:
Эта возможность появилась как следствие патологической лени программистов. Для понимания их логики, продемонтрирую пример, который покажет, как выглядел бы этот же самый код, если бы возможность отрицательной индексации отсутствовала. Пример:
 
<source lang=ruby>maccuBArray = [1, 2, 3, 4, 5]
Array[0] #-> 1
Array[Array.size - 5] #-> 1
Array[Array.size - 1] #-> 5
Array[4] #-> 5</source>
 
Метод <code>.size</code> возвращает количество элементов массива и его использование было бы необходимым, но в результате его использования код становится более громоздким, поэтому программисты решили эту проблему со свойственным им изяществом. Вернемся к исходной теме нашего повествования...
Строка 177:
Применим описанные выше свойства для демонстрации "альтернативного условного оператора" (сокращенно АУО). Для наглядности, решим задачку: "Даны два числа. Вывести слово 'больше', если первое число больше второго, 'меньше', если оно меньше. В случае равенства этих чисел, нужно вывести слово 'равны'." Решение:
 
<source lang=ruby>nepвoe_чucлo, втopoe_числo = 4, 5
puts ['равны','больше','меньше'][nepвoe_чucлo <=> втopoe_числo]</source>
 
Строка 184:
А что будет, если надо использовать не три варианта, а меньше? Хм. Вопрос вполне уместный. Давайте попытаем задачу: "Даны два числа. Вывести слово 'равны', если они равны и словно 'неравны', иначе." Возможное решение:
<source lang=ruby>nepвoe_чucлo, втopoe_числo = 4, 5
puts ['равны','неравны','неравны'][nepвoe_чucлo <=> втopoe_числo]</source>
 
Данное решение неоптимально, поскольку задействует дополнительную память для хранения дублирующего ответа. Первое, что приходит на ум — сократить массив до двух элементов. Решение:
<source lang=ruby>nepвoe_чucлo, втopoe_числo = 4, 5
puts ['равны','неравны'][nepвoe_чucлo <=> втopoe_числo]</source>