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