Приложения
Приложения
A. Язык программирования Ruby
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) числоДля задания строк можно использовать кавычки (") или апострофы (’). В первом случае распознаются и интерпретируются так называемые эскейп-последовательности (например, , ", , ) и выполняется подстановка результатов вычисления выражения 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 b’ здесь четыре символа: буква а, символ и буквы n и b "a b" всего три символа: буквы а и b разделены символомБазовые типы
Массив (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’Каждый символ регулярного выражения последовательно сравнивается с проверяемой строкой. Все, что не является указанными ниже спецсимволами или операторами, воспринимается, как обычный символ, рассматриваемый на простое совпадение.
A.2 Термы и выражения.
Термами в языке 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 В отличие от предыдущего случая параметров нет. Результат – вывод символа перевода строки 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 начинает выполнять цикл или итератор с самого начала.