A.1 Базовые типы. Базовыми типами языка Ruby являются числа, строки (объекты класса String), массивы (класс Array), диапазоны (Range), хэши или ассоциативные массивы (Hash), символы (Symbol) и регулярные выражения (объекты класса Regexp). Любое целое число x G Z может быть представлено объектом класса Fixnum (если величина |x| не слишком велика) или Bignum (иначе), но лишь конечное подмножество из несчётного множества действительных чисел R представимо в виде объектов класса Float, часто называемых числами с плавающей точкой.
Таблица A.1. Примеры чисел
Выражение | Значение | Комментарий |
123 | 123 | целое число – объект класса Fixnum |
–1234567890 | –1234567890345 | целое число – объект класса Bignum |
1_234_567_890 | 1234567890345 | подчёркивания в записи чисел игнорируются |
–123.45 | –123.45 | «действительное» число (класс Float) |
1.2345e+2 | 123.45 | экспоненциальная формы записи |
0xff | 255 | шестнадцатеричное (hexadeciamal) число |
037 | 31 | восьмеричное (octal) число |
0b1011 | 11 | двоичное (binary) число |
Для задания строк можно использовать кавычки (") или апострофы (’). В первом случае распознаются и интерпретируются так называемые эскейп-последовательности (например, \n, \", \t, \r) и выполняется подстановка результатов вычисления выражения expr вместо подстроки #{expr}. В обоих случаях последовательности \\ и \’ преобразуются в символы \ и ’ соответственно. Существуют и другие способы задания строк, некоторые из которых показаны в таблице А.2.
Таблица A.2. Примеры строк
Выражение | Значение | Комментарий |
"2 + 3 = #{2+3}" | "2 + 3 = 5" | подстановка вычисленного выражения |
’2 + 3 = #{2+3}’ | "2 + 3 = #{2+3}" | подстановка не выполняется |
%q(Язык Ruby) | "Язык Ruby" | аналог строки в апострофах |
%Q(#{2**32}) | "4294967296" | аналог строки в кавычках |
’a\nb’ | здесь четыре символа: буква а, символ \ и буквы n и b | |
"a\nb" | всего три символа: буквы а и b разделены символом \n |
Массив (Array) в Ruby – это набор (коллекция, множество) произвольных объектов (см. таблицу A.3).
Таблица A.3. Примеры массивов
Выражение | Значение | Комментарий |
[] | [] | пустой массив |
[0] | [0] | массив из одного элемента – числа 0 |
[1, 2.3, "Ruby"] | [1, 2.3, "Ruby"] | массив из трёх элементов |
[[1,2],[3]] | [[1, 2], [3]] | массив из двух массивов |
%w(Где ёж?) | "Где [ёж?"] | способ создания массива строк |
%w(Где\ же он?) | %w[Где же "он?"] | экранирование пробела |
%W(2 3 #{2*3}) | ["2", "3", "6"] | подстановка значения выражения |
Диапазон (Range) – последовательность объектов, которая включает (для e1..e2) или не включает (для e1...e2) в себя элемент e2. Используемый в качестве итератора диапазон передаёт в блок все свои элементы (как при вызове метода to_a, преобразующего диапазон в массив).
Таблица A.4. Примеры диапазонов
Диапазон | Соответствующий ему массив |
1..9 | [1, 2, 3, 4, 5, 6, 7, 8, 9] |
1 1 0 | [1, 2, 3,4, 5, 6, 7, 8, 9] |
3.. 1 | [] |
’d’..’n’ | ["d", "e", "g", "h", "i", "j", "k", "l", "m", "n"] |
Хэш (Hash) – это набор пар ключ—значение. Хэш схож с массивом, за исключением одной особенности – индексация производится с помощью объектов любых типов, кроме integer. Причем порядок обхода элементов не зависит от порядка вставки.
Примеры хэшей приведены ниже:
Таблица A.5. Примеры хэшей
Выражение | Значение | Комментарий |
Hash["3 О 2, "b" 1 a"] | {"a"=>1, "b"=>2,"c"=>3} | хэш из трех элементов |
Hash["a" => 1, "b" => 2] | {"a"1 => 1, "b" => 2} | хэш из двух элементов |
{"a"> 1}= | {"a"=> 100} | хэш из одного элемента |
Как видно из примера, для создания хэша часто используются литералы key => value. Ключ и значения находятся в паре, поэтому число аргументов должно быть четным.
Хэши имеют значение по умолчанию. Это значение возвращается каким-либо итератором при попытке обращения к ключу, не существующему в хэше. И этим значением является nil.
Регулярные выражения (объекты класса Regexp) используются для подбора шаблона строки. Для создания регулярных выражений нужно использовать литералы /…/ или %r…, а также конструктор Regexp.new. Отметим, что разные версии Руби используют разные средства для работы с регулярными выражениями.
При создании регулярных выражений могут идти следующие параметры:
Таблица A.6.
Параметр | Значение |
/…/i | не различать регистр |
/…/x | игнорировать пробелы и переводы строк |
/…/s | считать регулярное выражение |
С помощью регулярных выражений можно:
• Проверять, соответствует ли вся строка целиком заданному шаблону.
• Находить в строке подстроки, удовлетворяющие заданному шаблону.
• Извлекать из строки подстроки, соответствующие заданному шаблону.
• Изменять в строке подстроки, соответствующие шаблону.
Примеры использования регулярных выражений приведены в таблице А7.
Таблица A.7.
Параметр | Значение |
/Abc/ | совпадет только со словом ’Abc’ |
/Abc/i | совпадет со словами ’ABC’, ’abc’, ’Abc’ и т.д. |
/abc/ | совпадет с ’abc’, ’abc cba’ |
/abc.*def/s | совпадет с ’abckghfdkdef’ |
Каждый символ регулярного выражения последовательно сравнивается с проверяемой строкой. Все, что не является указанными ниже спецсимволами или операторами, воспринимается, как обычный символ, рассматриваемый на простое совпадение.
Термами в языке Ruby являются литералы (объекты базовых типов), результаты выполнения команд операционной системы, генерации символов и вызова методов, а также значения констант и переменных.
Вызов метода m объекта obj1 со списком параметров arg и блоком blk (иначе называемый посылкой сообщения m получателю obj) записывают в виде obj.m(arg){blk} или obj.m(arg) do blk end. Для вызовов, выполняемых вне классов («на верхнем уровне»), получателем является main – экземпляр класса Object, создаваемый при старте Ruby–программы. Примеры вызовов методов приведены в таблице A.8.
В языке Ruby имена используются для ссылок на константы, переменные, методы, классы и модули. В таблице A.9 перечислены зарезервированные слова, которые не могут быть использованы в качестве имён.
Имена констант должны начинаться с большой латинской буквы (от A до Z), за которыми может следовать любая последовательность больших и малых латинских букв, цифр и символов подчёркивания (_).
Переменные в языке Ruby бывают четырёх различных видов: локальные, экземпляра, класса и глобальные. Имена локальных переменных должны начинаться с малой латинской буквы (от a до z) или символа подчёркивания, за которыми может следовать любая последовательность больших и малых латинских букв, цифр и символов подчёркивания. В именах локальных переменных, состоящих из нескольких слов, рекомендуется использовать подчёркивание, например, day_week.
К именам переменных экземпляра вначале добавляется символ @ (например, @x), переменных класса – два таких символа (например, @@name), а глобальных переменных – символ $ (например, $_). Некоторые предопределённые объекты имеют имена, отступающие от этого правила.
Методы, не являющиеся переопределяемыми операторами (см. таблицу A.11), должны иметь имя, образованное по тем же правилам, что и имена локальных переменных. К имени метода может быть добавлен восклицательный (!) или вопросительный знак (?), либо символ =. Рекомендуется использовать такие имена для методов, изменяющих объект-получатель (self), возвращающих логическое значение и допускающих использование в левой части оператора присваивания соответственно.
Имена классов и модулей являются константами и следуют описанным выше правилам. Рекомендуется для констант, определяемых в классах, ис-
В случае отсутствия явного получателя им является объект self – тот экземпляр некоторого класса, в контексте которого происходит данный вызов.
Таблица A.8. Примеры вызовов методов
Вызов | Комментарий |
puts "Здравствуй, мир!" | Получатель – предопределённый объект main класса Object. Этот класс включает в себя модуль Kernel, имеющий метод puts, вызов которого эквивалентен вызову STDOUT.puts |
puts | В отличие от предыдущего случая параметров нет. Результат – вывод символа перевода строки \n |
2.+(3) | Получатель – число 2 (объект класса Fixnum). Параметр – число 3. Выражение 2+3 (см. таблицу A.11) эквивалентно данному вызову |
[1,2,3][0]=4 | Получатель – массив [1,2,3] (см. таблицу A.11). В результате вызова массив станет равным [4,2,3] |
"123".to_i | Получатель – строка "123". Метод to_i класса String без параметров возвращает целое число 123 |
) СО ( i _ 0 t 3" 2 1 | Параметр 8 указывает, что строку надо рассматривать, как число, записанное в восьмеричной системе счисления. Метод возвращает целое число 83 |
3.times do |i| pi end | Получатель – число 3. Параметров нет, но имеется блок. Метода times класса Integer выполняет этот блок, передавая в него последовательно значения 0, 1 и 2. В результате будут напечатаны три строки |
Получатель – экземпляр а класса Array, включающего в себя модуль Enumerable. Метод inject присваивает переменной s параметр (0) и вычисляет затем выражение s+x последовательно для всех элементов массива х, запоминая результат в s. Метод возвращает сумму элементов массива (число 15)
[1,2].to_i Получатель – массив [1,2]. Так как класс Array, его родительский класс Object и включённые в них модули не содержат метода с именем to_i, то возникает исключительная ситуация NoMethodError пользовать только большие буквы и символ подчёркивания, а при построении имён классов и модулей применять так называемый М1хеёСазе, когда каждое из слов, образующих сложное имя, пишется с большой буквы.
Таблица A.9. Зарезервированные слова языка Ruby
__FILE__ | and | def | end | in | or | self | unless |
_ LINE_ | begin | defined? | ensure | module | redo | super | until |
BEGIN | break | do | false | next | rescue | then | when |
END | case | else | for | nil | retry | true | while |
alias | class | elsif | if | not | return | undef | yield |
Таблица А.10. Некоторые предопределённые стандартные объекты
Имя | Класс | Назначение |
ARGF или $ | Object | Объект,предоставляющий доступ к конкатенации всех файлов,заданных в командной строке, или содержимому стандартного ввода (когда в командной строке нет аргументов) |
ARGV или $*Array | Array | Массив строк, содержащий аргументы командной строки запуска Ruby-программы |
ENV | Object | Подобный хэшу объект, содержащий значения переменных среды (environment) |
DATA | IO | Если программа содержит директиву __END__, то DATA содержит все строки файла программы, следующие за строкой с директивой __END__ |
RUBY_PLATFORM | String | Идентификатор платформы (операционной системы с дополнительными характеристиками), на которой выполняется программа |
RUBY_VERSION | String | Версия интерпретатора Ruby |
STDOUT | IO | Стандартный вывод, начальное значение $stdout |
__FILE__ | String | Имя файла, содержащего выполняемую программу |
__LINE__ | String | Номер текущей строки в программе |
Выражение представляет терм или несколько термов, объединённых с помощью перечисленных в таблице А.11 операторов. Приоритеты операторов, разделённых горизонтальными линиями, различны и убывают сверху вниз. Многие из операторов являются методами и могут быть переопределены. Примеры использования операторов приведены в таблице А.12.
Объект, предоставляющий доступ к конкатенации всех файлов, заданных в командной строке, или к содержимому стандартного ввода (когда в командной строке нет аргументов)
Массив строк, содержащий аргументы командной строки запуска Ruby–программы
Подобный хэшу объект, содержащий значения переменных среды (environment)
Если программа содержит директиву__END__, то DATA содержит все строки файла программы, следующие за строкой с директивой END
Идентификатор платформы (операционной системы с дополнительными характеристиками), на которой выполняется программа Версия интерпретатора Ruby Стандартный вывод, начальное значение $stdout Имя файла, содержащего выполняемую программу Номер текущей строки в программе
Таблица A.11. Операторы и их приоритеты
Операторы | Описание | Метод? |
[ ] | Ссылка на элемент массива или хэша | Да |
[ ] = | Присваивание элементу массива или хэша | Да |
** | Возведение в степень | Да |
!~ + - | Отрицание, дополнение, унарные + и - | Да |
* / % | Умножение, деление, нахождение остатка | Да |
+ - | Сложение, вычитание | Да |
>> << | Сдвиги вправо, влево | Да |
& | Побитовое «И» | Да |
^ | | «Исключительное Или», «Или» | Да |
<= < > => | Операторы сравнения | Да |
<=> == === | Проверки на равенство | Да |
!= | Проверка на неравенство | Нет |
=~ | Сравнение с образцом | Да |
!~ | Сравнение с образцом | Нет |
&& | Условное «И» | Нет |
|| | Условное «Или» | Нет |
.. ... | Операторы создания диапазонов | Нет |
? : | Тернарный оператор if-then-else | Нет |
= %= ~= /= -= | += Присваивание и присваивания с операцией | Нет |
|| < < || > > || || | Присваивания с операцией | Нет |
*= &&= ||= **= | Присваивания с операцией | Нет |
defined? | Проверка: определён ли символ? | Нет |
not | Логическое отрицание | Нет |
or and | Логические «Или» и «И» | Нет |
if unless | Условные выражения и модификаторы | Нет |
while until | Условные выражения и модификаторы | Нет |
begin end | Оператор создания блока | Нет |
Таблица A.12. Примеры использования операторов
Выражение | Комментарий |
a, b = b, a | Множественное (параллельное) присваивание позволяет легко обменять значения переменных |
b += c | Присваивание с операцией допустимо не только для сложения (см. таблицу A.11) и эквивалентно b = b + c |
a<=>b | –1, 0 или 1, если a меньше, равно или больше b |
c = if a < 0 | Оператор if-then-elsif-else-end может иметь много |
b = 0 | elsif частей, истинность условий в каждой из которых |
elsif a == 0 | проверяется последовательно (если условие if |
b = 1 | части не выполнено). Выражения, вычисляемые при |
else | выполнении условий, можно размещать на той же строке |
b = 2 | после then или двоеточия. Условный оператор возвращает |
end | значение последнего вычисленного выражения |
b=if 2<3:4 else 5 end | Переменная b станет равна 4 |
b=2<3 ? 4 : 5 | Тернарный оператор ?: делает то же самое |
b=-1; b=0 if b<0 | Модификатор if часто удобнее |
b=-1 unless b<0 = b 1 – = b | Оператор unless проверяет ложность условия |
b=i=0 | Оператор while, называемый циклом, в отличие от |
c = while i < 5 | условного оператора не возвращает значения. |
b += i | В результате выполнения данной программы переменная i |
i += 1 | станет равна 5, b примет значение 10 (сумма всех чисел |
end | от 0 до 4), а переменная c – значение nil |
i=1; i+=i*i while (i<9) | Модификатор while сделает переменную i равной 42 |
i=1;i+=i until(i>10) | После завершения этой программы i станет равно 16, ибо until выполняет тело цикла, пока условие ложно |
s=0 | Неявно преобразуется в s = 0 |
for i in 1..3 | (1..3).each do |i| |
s += i | s += i |
end | end |
В дополнение к этому break немедленно прекращает выполнение цикла, передавая управление на следующую за ним инструкцию; redo начинает выполнять цикл или итератор сначала, но не перевычисляет условие продолжения (для цикла) и не переходит к следующему элементу коллекции (для итератора); next прерывает выполнение текущей итерации и начинает выполнение следующей; retry начинает выполнять цикл или итератор с самого начала.