Предыдущий раздел Уровень выше Следующий раздел

Объекты и методы

При описании Ruby было отмечено, что он является объектно-ориентированным языком программирования. Это означает что все, с чем работает программа, является объектом, при этом вычисление осуществляется посредством взаимодействия объектов. Каждый объект есть представитель (экземпляр) некоторого класса и его поведение (функциональность) определяется именно им. Тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия, называемые методами. Для того чтобы применить метод к некоторому объекту используется оператор вызова метода, обозначаемый символом . (точка): после указания объекта ставится точка, а затем указывается применяемый метод.

Пока мы не будем вдаваться в особенности объектно-ориентированного программирования (тем более, что в различных языках программирования по разному трактуется концепция ООП), а лишь познакомимся с некоторыми "простейшими" объектами, без которых невозможно приступать к дальнейшему изучению языка. Это представители так называемых "встроенных" классов. Среди них:

true
логическая величина, означающая истину; единственный представитель класса TrueClass;
false
логическая величина, означающая ложь; единственный представитель класса FalseClass;
числа
представители класса Numeric, который в качестве подклассов содержит дробные (Float) и целые числа (Integer);
строки
представители класса String;
nil
"ничто"; единственный представитель класса NilClass.
моменты времени
представители класса Time.

Числа

Знакомство с представителями различных классов начнем с чисел. Целые числа в Ruby являются экземплярами класса Integer, который объединяет два подкласса: Fixnum или Bignum. Объектами класса Fixnum являются те целые, чье двоичное представление способно разместится в машинном слове (31 бит на большинстве компьютеров). Если число выходит за границы указанного диапазона, то оно автоматически преобразуется в объект класса Bignum, чей диапазон изменения ограничивается только объемом доступной памяти. Если в результате работы с объектами класса Bignum итоговое значение попадает в диапазон, задаваемый классом Fixnum, то выдаваемый результат преобразуется в экземпляр класса Fixnum.

ЧислоКласс
123456Fixnum
123_456Fixnum (подчеркивание игнорируется)
-543отрицательное Fixnum
123_456_789_123_456Bignum
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_f1234.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*  %+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, обеспечивающий форматный вывод. Сразу после имени оператора указывается строка формата, содержащая как обычные символы, выводимые на печать, так и спецификации преобразования, которые вызывают преобразование и печать остальных аргументов в том порядке, в каком они перечислены. Каждая спецификация преобразования начинается с символа % и заканчивается символом-спецификатором преобразования. Между % и символом-спецификатором в порядке, указанным ниже, могут располагаться следующие модификаторы:

Основные литеры-спецификаторы и разъяснение их смысла приводятся в следующей таблице.

ЛитераАргументВид печати
dFixnum, Bignum печать целого числа
sString печать строки
fFloat печать дробного числа

Включите в файл следующие операторы форматной печати и посмотрите на результаты выполнения:

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 "
(скачать программу)

Предыдущий раздел Уровень выше Следующий раздел