При описании Ruby было отмечено, что он является объектно-ориентированным языком программирования. Это означает что все, с чем работает программа, является объектом, при этом вычисление осуществляется посредством взаимодействия объектов. Каждый объект есть представитель (экземпляр) некоторого класса и его поведение (функциональность) определяется именно им. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия, называемые методами. Для того чтобы применить метод к некоторому объекту используется оператор вызова метода, обозначаемый символом . (точка): после указания объекта ставится точка, а затем указывается применяемый метод.
Пока мы не будем вдаваться в особенности объектно-ориентированного программирования (тем более, что в различных языках программирования по разному трактуется концепция ООП), а лишь познакомимся с некоторыми "простейшими" объектами, без которых невозможно приступать к дальнейшему изучению языка. Это представители так называемых "встроенных" классов. Среди них:
- true
- логическая величина, означающая истину; единственный представитель класса TrueClass;
- false
- логическая величина, означающая ложь; единственный представитель класса FalseClass;
- числа
- представители класса Numeric, который в качестве подклассов содержит дробные (Float) и целые числа (Integer);
- строки
- представители класса String;
- nil
- "ничто"; единственный представитель класса NilClass.
- моменты времени
- представители класса Time.
Числа
Знакомство с представителями различных классов начнем с чисел. Целые числа в Ruby являются экземплярами класса Integer, который объединяет два подкласса: Fixnum или Bignum. Объектами класса Fixnum являются те целые, чье двоичное представление способно разместится в машинном слове (31 бит на большинстве компьютеров). Если число выходит за границы указанного диапазона, то оно автоматически преобразуется в объект класса Bignum, чей диапазон изменения ограничивается только объемом доступной памяти. Если в результате работы с объектами класса Bignum итоговое значение попадает в диапазон, задаваемый классом Fixnum, то выдаваемый результат преобразуется в экземпляр класса Fixnum.
Число | Класс |
---|---|
123456 | Fixnum |
123_456 | Fixnum (подчеркивание игнорируется) |
-543 | отрицательное Fixnum |
123_456_789_123_456 | Bignum |
0xaabb | шестнадцатеричное |
0377 | восьмеричное |
-0b1010 | двоичное (отрицательное) |
0b001_001 | двоичное |
При записи целых чисел сначала указывается его знак (знак + обычно опускается). Далее следует основание системы счисления, в которой задается число (если оно отлично от 10): 0 - для восьмеричной, 0x - для шестнадцатеричной, 0b - для двоичной. Затем идет последовательность цифр, выражающих число в данной системе счисления. При записи больших чисел можно использовать символ подчеркивания, который игнорируется при обработке. В таблице представлены целые числа и указана их принадлежность к тому или иному классу.
Дробные числа задаются в десятичной системе счисления, при этом для отделения дробной части используется символ . (точка). Такие числа являются экземплярами класса Float, например, 12.34. Для задания дробных чисел может быть применена и экспоненциальная форма записи: два различных представления -.1234е2 и 1234е-2 задают одно и тоже число 12.34.
Для вычисления арифметических выражений применяются следующие операторы: + (сложение), - (вычитание), * (умножение), / (деление), % (остаток от деления), ** (возведение в степень). Порядок вычисления определяется стандартными приоритетами операций, а для его изменения используются круглые скобки. Заметим, что если все аргументы выражения целые числа, то и результат будет целым, если же хотя бы одно из чисел, входящих в выражение - дробное, то и результат будет экземпляром класса Float.
Пример
Создайте файл с именем object.rb, в который поместите следующий фрагмент. Выполните программу и объясните результат.
puts 5/8 # 0 puts 5.0/8 # 0.625 puts 2**1000 puts ((2*500+1)*(2**500-1))
Отметим еще несколько методов, используемых при работе с числами (т. е. представителями класса Numeric). Среди них: ceil (нахождение наименьшего целого не меньшего, чем данное), floor (наибольшее целое, не большее данного), round (округление до ближайшего целого), получение абсолютной величины числа abs. Ниже приведены примеры использования этих методов.
puts 12.34.ceil # 13 puts 12.34.floor # 12 puts -12.ceil # -12 puts -12.floor # -12 puts 12.34.round # 12 puts 12.54.round # 13 puts -34.56.abs # 34.56
В Ruby имеется несколько методов, позволяющих преобразовывать объекты одного класса в другой.
Метод | Назначение метода | Пример использования |
Результат |
---|---|---|---|
to_f | Преобразовать объект в экземпляр класса Float | 1234.to_f | 1234.0 |
to_i | Преобразовать объект в экземпляр класса Fixnum или Bignum | -12.34.to_i | -12 |
В последнем примере первая точка отделяет дробную часть числа, а вторая является оператором вызова метода.
Строки
Другим столь же распространенным классом является класс String. К этому классу относятся произвольные строки символов, заключенные в апострофы или кавычки, например, 'hello', 'раз, два, три', "привет всем". Есть несколько альтернативных способов задания каждого из этих видов строк.
Для задания строки в апострофах можно использовать любой из способов представленных ниже.
puts 'hello' # hello puts %q/hello/ # hello puts %q(hello) # hello
Два подряд идущих символа \ внутри такой строки заменяются на один.
puts 'hell\\o' # hell\o puts %q(hell\\o) # hell\o
Для того чтобы внутрь строки, заключенной в апострофы, вставить апостроф, следует предварительно "экранировать" его символом \ (обратный слеш).
puts 'hell\'o' # hell'o puts %q(hell\'o) # hell\'o puts 'hel"l"o' # hel"l"o
Для создания строки, заключенной в кавычки, следует либо просто заключить ее в кавычки, либо использовать конструкции %Q или %, после которых указывается строка, обрамленная с двух сторон одним и тем же символом, отличным от цифр и букв (можно использовать также пару любых скобок). Ниже перечислено несколько способов задания строки "hello".
"hello" %Q/hello/ %Q{hello} %Q(hello) %Q!hello! % %(hello) %!hello! %*hello* %+hello+
Для включения внутрь такой строки символа ", его также следует экранировать символом \:
puts "Say \"Hello\"" # Say "Hello"
Строка, заключенная в кавычки, позволяет интерпретировать последовательности символов, начинающиеся с символа \ такие, например, как \n (символ перехода на новую строку) и \t (табуляция). Другой особенностью строк, заключенных в кавычки, является возможность использования подстановки: если строка содержит некоторое выражение, ограниченное символами #{ и }, то оно заменяется на результат его вычисления. Добавьте в программу следующие строки и проанализируйте полученный вывод.
puts "a \t b"; puts 'a \t b' puts "выражение 3*5+8 равно #{3*5+8}" puts 'выражение 3*5+8 равно #{3*5+8}' puts "работа с целыми числами: 5/8 = #{5/8}" puts "перевод в класс Float: 5/8 = #{5/8.to_f}"
К строкам могут применяться методы to_i и to_f. При преобразовании к целому числу отбрасывается оставшаяся часть строки, как только встречается символ, отличный от цифры (исключение - знак плюс или минус в первой позиции строки). Аналогичные правила применяются и при преобразовании к дробному числу. Единственным отличием является то, что первая найденная точка рассматривается как разделитель между целой и дробной частями. Следующий фрагмент иллюстрирует сказанное:
puts "-12.34".to_i puts "12.34".to_f puts "+12:34".to_i puts "12qq34".to_f
Для получения строки, содержащей символ с заданным ASCII кодом, используется метод chr, например,
puts 209.chr
Следует помнить, что этот метод может быть применен только к положительному целому числу, не превышающему 255.
Класс String предоставляет большое число методов для работы со строками, некоторые из которых представлены в следующей таблице.
Назначение и пример использования метода | Результат | |
---|---|---|
+ | Сцепление строк "мол" + "око" |
"молоко" |
* | Повтор строки "ab" * 3 |
"ababab" |
[ ] | Возвращает ASCII-код символа, находящегося на указанной позиции строки (отсчет начинается с нуля) "abcdef"[0] "abcdef"[0].chr |
97 "a" |
[нач..кон] | Возвращает подстроку, заключенную в указанном диапазоне (включая концы) "abcdef"[0..3] |
"abcd" |
[нач, дл] | Возвращает подстроку, начинающуюся с указанной позиции и имеющую заданную длину "abcdef"[0,3] |
"abc" |
capitalize | Заменяет первый символ строки (если он является буквой латинского алфавита) на заглавную "abc".capitalize |
"Abc" |
chop | Удаляет последний символ строки (два символа, если они есть "\r\n") "abcdef".chop |
"abcde" |
delete | Удаляет указанные символы из строки, может указываться диапазон изменения символов "abcdef".delete('ea') "abcdef".delete('a-c') |
"bcdf" "def" |
index | Определяет номер позиции, с которой начинается указанная подстрока; можно указывать номер позиции, с которой начинается поиск "abcdabcd".index("cd") "abcdabcd".index("cd",3) |
2 6 |
length size |
Определяют длину строки (в байтах) "12345678".length "12345678".size |
8 8 |
ljust rjust center |
Дополняют строку пробелами до указанной ширины, выравнивая соответственно по левому краю, по правому краю или по центру "123".ljust(8) "123".rjust(8) "123".center(8) |
"123 " " 123" " 123 " |
reverse | Возвращает строку, содержащую символы в обратном порядке "1234567".reverse |
"7654321" |
strip | Удаляет пробелы в начале и конце строки " 123 ".strip |
"123" |
squeeze | Оставляет в группе повторяющихся символов только один; допускается задание списка символов, на которых распространяется данное действие "22---23**".squeeze "22---23**".squeeze('*-') |
"2-23*" "22-23*" |
tr | Заменяет все найденные вхождения символов на заданные "22+33=55".tr('25','47') |
"44+33=77" |
Отдельного упоминания заслуживает метод eval, позволяющий динамически выполнять другие методы. Этот метод анализирует переданную ему строку, рассматривая ее как часть программы, и выполняет ее. Обратите внимание, что при вызове этого метода используется не точечная, а функциональная форма записи:
puts eval("2**10") puts eval('"мол".size * "око".size') # 9
Время и дата
Экземпляр класса Time в языке Ruby содержит информацию о дате, времени и временной зоне. Для создания объекта этого класса, содержащего текущие дату и время, используется метод now. Такие объекты могут являться аргументами операций + и -:
puts Time.now puts Time.now+60 # добавили 60 секунд к текущему времени puts Time.now-60 # отняли 60 секунд от текущего времени
Отметим некоторые методы этого класса, для вызова которых используется точечная нотация.
Метод | Назначение метода |
---|---|
sec | Получить число секунд |
min | Получить число минут |
hour | Получить число часов |
mday и day | Получить день месяца |
mon и month | Получить номер месяца |
year | Получить год |
wday | Получить номер дня недели |
yday | Получить номер дня в году |
zone | Получить информацию о временной зоне |
to_i | Получить число секунд, прошедших с 1 января 1970 года |
В языке Ruby имеется метод sleep, который заставляет программу "заснуть" на число секунд, указанное в качестве аргумента метода. Посмотрите на пример использования методов для работы с объектами класса Time.
puts "До Нового года осталось #{365-Time.now.yday} дней" puts Time.now puts "Подождем 10 секунд." sleep(10) puts Time.now
Вывод данных
Мы уже видели, как осуществляется вывод информации в Ruby. Познакомимся с другими операторами, обеспечивающими печать данных. Создайте файл print.rb, включите в него следующий текст и посмотрите на результат выполнения полученной программы.
puts "puts всегда завершается переходом к новой строке." print "А оператор print не делает этого по умолчанию, " print "как вы видите в этом примере.\n" print "print может быть вызван сразу ", "с несколькими аргументами.\n"
Оператор p подобен оператору puts и отображает объекты в виде, понятном человеку. Не следует использовать его для вывода русских букв - он печатает их ASCII-коды.
p Time.now, Time.now+3600
Значительно большими возможностями обладает оператор printf, обеспечивающий форматный вывод. Сразу после имени оператора указывается строка формата, содержащая как обычные символы, выводимые на печать, так и спецификации преобразования, которые вызывают преобразование и печать остальных аргументов в том порядке, в каком они перечислены. Каждая спецификация преобразования начинается с символа % и заканчивается символом-спецификатором преобразования. Между % и символом-спецификатором в порядке, указанным ниже, могут располагаться следующие модификаторы:
- флаги (в любом порядке):
- указывает на то, что преобразованный аргумент должен быть прижат к левому краю поля; + предписывает всегда печатать число со знаком; 0 указывает, что числа должны дополняться ведущими нулями до всей ширины поля; пробел если первый печатаемый символ не знак, то числу должен предшествовать пробел; - число, задающее минимальную ширину поля;
- точка, отделяющая указатель ширины поля от указателя точности;
- число, задающее точность.
Основные литеры-спецификаторы и разъяснение их смысла приводятся в следующей таблице.
Литера | Аргумент | Вид печати |
---|---|---|
d | Fixnum, Bignum | печать целого числа |
s | String | печать строки |
f | Float | печать дробного числа |
Включите в файл следующие операторы форматной печати и посмотрите на результаты выполнения:
printf "%8s~~%-8s\n", "abcd", "abcd" printf "%8-s::%8s\n", "abcd", "abcd" printf "%06d\n", 2**10; printf "%+6d\n", 2**10 printf "%6d\n", 2**10; printf "%+6d\n", 2.5*1.3 printf "%4.3f\n", 2.5*1.3 printf "-2/7=%+1.6f, -2/6=%2.15f\n", -2/7.to_f, -2/6.to_f
Обратите внимание, что строка формата заключается в двойные кавычки и может содержать специальные последовательности символов. Одной из них является \n. Эта последовательность дает указание интерпретатору Ruby продолжить вывод информации со следующей строки (newline). Другой часто используемой последовательностью является \t (табуляция), которая передвигает фокус вывода к следующей позиции табуляции.
puts "*\t*\t*\t*\t*" puts " 1234567 1234567 1234567 1234567 "