sub2 = str2.scan(/(.)(c.)/)
# sub2 теперь равно [ ["A","ca"], ["l","со"], ["i","со"] ]
Если при вызове задан блок, то метод поочередно передает этому блоку найденные значения:
str3 = "Kobayashi"
str3.scan(/["aeiou]+[aeiou]/) do |x|
print "Слог: #{x}\n" end
Этот код выводит такой результат:
Слог: Ko
Слог: ba
Слог: уа
Слог: shi
2.15. Преобразование символов в коды ASCII и обратно
В Ruby символ представляется целым числом. Это поведение изменится в версии 2.0, а возможно и раньше. В будущем предполагается хранить символы в виде односимвольных строк.
str = "Martin"
print str[0] # 77
Если в конец строки дописывается объект типа Fixnum
str2 = str << 111 # "Martino"
2.16. Явные и неявные преобразования
На первый взгляд, методы to_s
to_str
могут вызвать недоумение. Ведь оба преобразуют объект в строковое представление, так?Но есть и различия. Во-первых, любой объект в принципе можно как-то преобразовать в строку, поэтому почти все системные классы обладают методом to_s
to_str
в системных классах не реализуется никогда.Как правило, метод to_str
to_s
— это явное преобразование, а метод to_str
— неявное.Я уже сказал, что ни в одном системном классе не определен метод to_str
to_str
(если такой метод существует в соответствующем классе).Первое, что приходит на ум, — подкласс класса String
String
, уже является строкой, так что определять метод to_str
излишне.А вот пример из реальной жизни. Класс Pathname
String
).require 'pathname'
path = Pathname.new("/tmp/myfile")
name = path.to_s # "/tmp/myfile"
name = path.to_str # "/tmp/myfile" (Ну и что?)
# Вот где это оказывается полезно...
heading = "Имя файла равно " + path
puts heading# " Имя файла равно /tmp/myfile"
В этом фрагменте мы просто дописали путь в конец обычной строки "Имя файла равно"
+
ожидает, что второй операнд — тоже строка. Но так как в классе Pathname
есть метод to_str
, то он вызывается. Класс Pathname
«маскируется» под строку, то есть может быть неявно преобразован в String
.На практике методы to_s
to_str
обычно возвращают одно и то же значение, но это необязательно. Неявное преобразование должно давать «истинное строковое значение» объекта, а явное можно расценивать как «принудительное» преобразование.Метод puts
to_s
объекта, чтобы получить его строковое представление. Можно считать, что это неявный вызов явного преобразования. То же самое справедливо в отношении интерполяции строк. Вот пример:class Helium
def to_s
"He"
end
def to_str
"гелий"
end
end
e = Helium.new
print "Элемент "
puts e # Элемент He.
puts "Элемент " + e # Элемент гелий.
puts "Элемент #{e}" # Элемент He.
Как видите, разумное определение этих методов в собственном классе может несколько повысить гибкость применения. Но что сказать об идентификации объектов, переданных методам вашего класса?
Предположим, например, что вы написали метод, который ожидает в качестве параметра объект String
File.new
— строка.Решить эту проблему просто. Если вы ожидаете на входе строку, проверьте, имеет ли объект метод to_str
def set_title(title)
if title.respond_to? :to_str
title = title.to_str
end
# ...
end