s2 = %q*\r - это control-M, a \n - это control-J.*
2.3. Встроенные документы
Для представления длинной строки, занимающей несколько строк в тексте, можно, конечно, воспользоваться обычными строками в кавычках:
str = "Три девицы под окном
Пряли поздно вечерком..."
Но тогда отступ окажется частью строки.
Можно вместо этого воспользоваться встроенным документом, изначально предназначенным для многострочных фрагментов. (Идея и сам термин заимствованы из более старых языков.) Синтаксически он начинается с двух знаков <<
, за которыми следует концевой маркер, нуль или более строк текста и в завершение тот же самый концевой маркер в отдельной строке:
str = <
Три девицы под окном
Пряли поздно вечерком...
EOF
Но следите внимательно, чтобы после завершающего концевого маркера не было пробелов. В текущей версии Ruby маркер в такой ситуации не распознается.
Встроенные документы могут быть вложенными. В примере ниже показано, как передать методу три представленных таким образом строки:
some_method(<
первый кусок
текста...
str1
второй кусок...
str2
третий кусок
текста.
str3
По умолчанию встроенный документ ведет себя как строка в двойных кавычках, то есть внутри него интерпретируются управляющие последовательности и интерполируются выражения. Но если концевой маркер заключен в одиночные кавычки, то и весь документ ведет себя как строка в одиночных кавычках:
str = <<'EOF'
Это не знак табуляции: \t
а это не символ новой строки: \n
EOF
Если концевому маркеру встроенного документа предшествует дефис, то маркер может начинаться с красной строки. При этом удаляются только пробелы из той строки, на которой расположен сам маркер, но не из предшествующих ей строк документа.
str = <<-EOF
Каждая из этих строк
начинается с пары
пробелов.
EOF
Опишу стиль, который нравится лично мне. Предположим, что определен такой метод margin
:
class String
def margin
arr = self.split("\n") # Разбить на строки.
arr.map! {|x| x.sub!(/\s*\|/,"")) # Удалить начальные символы.
str = arr.join("\n") # Объединить в одну строку.
self.replace(str) # Подменить исходную строку.
end
end
Для ясности я включил подробные комментарии. В этом коде применяются конструкции, которые будут рассмотрены ниже —
как в этой, так и в последующих главах. Используется этот метод так:
str = <
|Этот встроенный документ имеет "левое поле"
|на уровне вертикальной черты в каждой строке.
|
| Можно включать цитаты,
| делать выступы и т.д.
end
В качестве концевого маркера естественно употребить слово end
. (Впрочем, это дело вкуса. Выглядит такой маркер как зарезервированное слово end
, но на самом деле этот выбор ничуть не хуже любого другого.) Каждая строка начинается с символа вертикальной черты, но эти символы потом отбрасываются вместе с начальными пробелами.
2.4. Получение длины строки
Для получения длины строки служит метод length
. У него есть синоним size
.
str1 = "Карл"
x = str1.length # 4
str2 = "Дойль"
x = str2.size # 5
2.5. Построчная обработка
Строка в Ruby может содержать символы новой строки. Например, можно прочитать в память файл и сохранить его в виде одной строки. Применяемый по умолчанию итератор each в этом случае перебирает отдельные строки:
str = "Когда-то\nдавным-давно...\nКонец\n"
num = 0
str.each do |line|
num += 1
print "Строка #{num}: #{line}"
end
Выполнение этого кода дает следующий результат:
Строка 1: Когда-то
Строка 2: давным-давно...
Строка 3: Конец
Альтернативно можно было бы воспользоваться методом each_with_index
.
2.6. Побайтовая обработка
Поскольку на момент написания этой книги язык Ruby еще не поддерживал интернационализацию в полной мере, то символ и байт —
по существу одно и то же. Для последовательной обработки символов пользуйтесь итератором each_byte
:
str = "ABC"
str.each_byte {|char| print char, " " }
#Результат: 65 66 67.