Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
x = 14142y = 31416r1.include?(x) # falser1.include?(у) # trueУ этого метода есть также синоним
member?А как он работает? Как интерпретатор определяет, принадлежит ли объект диапазону? Просто путем сравнения с границами (поэтому проверка принадлежности диапазону возможна лишь, если определен осмысленный оператор
<=>(a..b).include?(x)x >= a and x <= bs1 = "2".."5"str = "28"s1.include?(str) # true (неправильно!)6.2.5. Преобразование в массив
Когда диапазон преобразуется в массив, интерпретатор последовательно вызывает метод
succr = 3..12arr = r.to_a # [3,4,5,6,7,8,9,10,11,12]Ясно, что для диапазонов чисел типа
Float6.2.6. Обратные диапазоны
Имеет ли смысл говорить об обратном диапазоне? И да, и нет. Следующий диапазон допустим:
r = 6..3x = r.begin # 6y = r.end # 3flag = r.end_excluded? # falseКак видите, мы можем определить обе границы и узнать, что правая граница включена. Но этим перечень возможных операций практически исчерпывается.
arr = r. to_a # []r.each {|x| p x } # Ни одной итерации.y = 5r.include?(у) # false (для любого значения y)Означает ли это, что обратные диапазоны всегда бесполезны? Вовсе нет. В некоторых случаях разумно инкапсулировать границы в один объект.
На самом деле массивы и строки часто принимают обратные диапазоны в качестве индексов, поскольку индексация для них начинается с 0, если отсчитывать от левой границы, и с -1 — если от правой. Поэтому допустимы такие выражения:
string = "flowerystr1 = string[0..-2] # "flower"str2 = string[1..-2] # "lower"str3 = string[-5..-3] # "owe" (по существу, прямой диапазон)6.2.7. Оператор переключения
Диапазон в составе условия обрабатывается особым образом. В этом случае
..Такой прием, позаимствованный из языка Perl, бывает полезен. Но понять, как он работает, довольно трудно.
Представьте себе исходный текст программы на Ruby, в который встроена документация, ограниченная маркерами
=begin=endloop do break if eof? line = gets puts line if (line=~/=begin/)..(line=~/=end/)end«Волшебство» объясняется принципом работы оператора переключения.
Во-первых, надо осознать, что «диапазон» сохраняет свое состояние, хотя оно и скрыто. Когда становится истинным условие, заданное в качестве левой границы, сам диапазон принимает значение
truefalseТакое поведение полезно во многих случаях, в частности для разбора HTML-документов или конфигурационных файлов, разбитых на разделы, выбора диапазонов элементов из списков и т.д.
Но лично мне такой синтаксис не нравится. Недовольны им и многие другие, включая и самого Маца. Возможно, в будущем эта возможность будет исключена из Ruby. Однако я покажу удобный способ реализовать ту же функциональность по-другому.
Что меня не устраивает в операторе переключения? В контексте предыдущего примера рассмотрим строку, начинающуюся с маркера
=begin=~truefalseFixnumnil0nilОднако при попытке сконструировать диапазон от
0nilrange = 0..nil # Ошибка!Далее, напомню, что в Ruby только
falsenilputs "hello" if x..y# Печатается "hello" для любого допустимого диапазона x..y.Но предположим, что мы сохранили эти значения в переменных, а потом из них сконструировали диапазон. Все перестанет работать, так как проверка всегда дает
trueloop do break if eof? line = gets start = line=~/=begin/ stop = line=~/=end/ puts line if start..stopendА что если сам диапазон поместить в переменную? Тоже не получится — проверка снова дает
trueloop do
