Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Ruby / ruby_notes

.pdf
Скачиваний:
105
Добавлен:
06.06.2015
Размер:
215.34 Кб
Скачать

§ 1. Введение

1

§ 1. Введение

Данное пособие предназначено для студентов-первокурсников, изу• чающих Ruby — современный интерпретируемый объектно-ориенти- рованный язык программирования. Оно не является справочником по классам и методам стандартных библиотек данного языка, а предназна• чено для знакомства с основами программирования.

Программы, использующие данный язык, хранятся в текстовых фай• лах с расширением rb. Запуск программы с именем XXXX.rb осуще• ствляется командой

ruby XXXX.rb

Интепретатор Ruby

Ruby является интерпретируемым языком. Это означает, что вы• полняется непосредственно исходный код программы, а не специально подготовленные файлы с наборами машинных команд, как в случаях использования компилятора.

Преимуществом интерпретатора являются простота использования и машинно-независимость, так как у них на выходе нет никакого машин• ного кода. Таким образом программа, созданная в одной операционной системе, будет без изменений работать в другой.

Отметим, однако, что программа, использующая для своего выпол• нения интерпретатор, как правило, работает значительно медленнее (программа на Ruby потребует приблизительно в 300 раз больше вре• мени на выполнение, чем аналогичная программа на языке C).

Среды программирования

Для создания программ нужен редактор — средство создания и изме• нения текстовых файлов, содержащих инструкции языка программиро• вания. В последнее время получили распространение, так называемые, интегрированные среды разраборки (IDE), позволяющие не только ре• дактировать тексты, но и пользоваться интерактивной документацией, средствами тестирования и отладки программ. Такие средства дают до• полнительные возможности при разработке больших программых про• ектов. На данный момент наиболее удобны Eclipse и Jedit, позволяю• щие проводить синтаксический анализ текстов программ и обеспечива• ющие доступ к описанию стандартных библиотек Ruby.

2

Среди программистов на Ruby распростанены также редакторы SciTe (входящий в стандатную поставку Ruby для ОС Windows), Anjuta и FreeRIDE.

Кроме вышеперечисленных можно использовать любой текстовый редактор (редактор plain-текста): Emacs, Kedit в Linux или Notepad в Windows-системах.

Напомним, что различные операционные системы используют не только отличающиеся наборы машинных команд (что не важно в случае интерпретатора), но и разные кодовые таблицы для представления сим• волов национальных алфавитов (например, Windows и Linux для коди• рования кириллицы). Мы рекомендуем использовать кодировку UTF-8 для ваших файлов с программами, что гарантирует отсутствие проблем с использованием русских букв в комментариях и текстах программы.

Тест программы

Программа на языке Ruby есть последовательность инструкций (утверждений, предложений). Каждая инструкция по умолчанию закан• чивается концом строки.

Если требуется разместить несколько инструкций на одной строке, то их разделяют символом ; (точка с запятой).

print "H"; print "e"; puts "llo, World!"

Если инструкция не помещается на одной строке, то символ \ сигна• лизирует о том, что ее продолжение располагается в следующей строке.

puts "H\ e\

l\

l\

o, World!"

Комментарии

Для того чтобы сделать программу более понятной человеку, кото• рый ее читает, вставляются комментарии. Специальные конструкции позволяют сделать часть текста невидимой для интерпретатора.

Однострочные комментарии начинаются с символа # и продолжа• ются до конца строки.

Многострочные комментарии заключают в специальные «скобки»: все, что располагается между строками =begin и =end, считается ком• ментарием. Заметим, что лексемы =begin и =end должны начинаться

§ 2. Базовые классы

3

с самого начала строки. Пробелы или другие символы перед ними не допустимы!

=begin

Это

комментарий

=end

# Это тоже комментарий

print "Hello, World!" # команда печати

§ 2. Базовые классы

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

Все, с чем работает программа, является объектом, при этом вы• числение осуществляется посредством взаимодействия объектов.

Каждый объект есть представитель (экземпляр) некоторого класса и его поведение (функциональность) определяется именно им. Все объ• екты, которые являются экземплярами одного класса, могут выполнять одни и те же действия, называемые методами.

Для применения метода к объекту используется оператор вызова метода, обозначаемый символом . (точка): после указания объекта ста• вится точка, а затем указывается применяемый метод (не следует пу• тать с десятичной точкой). По традиции имена методов начинаются с маленькой буквы.

Классы

Ruby содержит большое количество «встроенных» классов. Чаще всего мы будем работать с числами, строками, логическими величинами

идатами.

Кобъекту любого класса можно применить методы «печати» print

иputs, которые преобразуют объект к строковому виду и отображают получившуюся строку. Метод puts добавляет к получившейся строке символ перевода строки "\n".

Метод class возвращает название класса, к которому принадлежит объект:

puts 11111111111111111111111111.class # => Bignum puts 3.14.class # => Float

puts "Hello".class # => String

4

Все классы в Ruby объединены в единую «иерархию» классов. Основой всех классов является класс Object. У него нет «родитель• ского» класса. Для всех других классов метод superclass возвращает имя родительского класса.

puts Bignum.superclass # => Integer puts String.superclass # => Object

Логические величины

Классы TrueClass и FalseClass содержат только по одному эк• земпляру своего класса, соответственно: true — логическую величину, означающую истину и false — логическую величину ложь.

Перечислим основные операции в порядке убывания приоритета:

отрицание

!

конъюнкция (логическое И)

&&

дизъюнкция (логическое ИЛИ)

||

Следующая пара операторов имеет одинаковый приоритет, поэтому по• рядок вычисления выражений определяется скобками

конъюнкция (логическое И)

and

дизъюнкция (логическое ИЛИ)

or

puts (true or false and true) # => true

Отметим, что в языках программирования не используется импли• кация, так как она выражается через другие операции: A → B = !A || B.

Результаты выполнения операторов сравнения ==, <=, <, >=, > также являются логическими величинами.

Числа

Числа являются представителями класса Numeric, который в каче• стве подклассов содержит дробные (Float) и целые числа (Integer).

Множествам целых Z и действительных чисел R в большинстве языков программирования соответствуют их машинные аналоги. В слу• чае языка Ruby используемые в программах переменные и константы классов Integer и Float принимают значения из множеств ZM и RM соответственно.

Отметим, что Ruby в отличии от многих других языков позволяет оперировать целыми числами из практически неограниченного диапазо• на значений (ограничение накладывается только возможностями ваше•

§ 2. Базовые классы

5

го компьютера). Пока целые числа находятся в диапазоне от −230 до 230−1, они являются экземплярами класса Fixnum. Если в результате расчетов получившийся результат не входит в указанный диапазон, то он автоматически преобразуется в экземпляр класса Bignum и наобо• рот, если в результате работы с объектами класса Bignum, получается число из диапазона от −230 до 230−1, то оно автоматически преобразу• ется к объекту типа Fixnum.

Целые числа не обязательно должны задаваться в десятичной си• стеме счисления. Возможно использование систем счисления с осно• ваниями 2, 8 и 16. Признаком того, что далее следует 8-ричное число является указание ведущего нуля, а признаком двоичного или 16-рично• го числа — комбинация 0b (0B) или 0x (0X) соответственно, указанная непосредственно перед числом.

puts 077 # => 63 puts 0b111 # => 7 puts 0xA # => 10

Отметим, что метод преобразования к строковому виду to_s, при• менимый к объектам класса Integer, допускает указание аргумента — целого числа (от 2 до 36), являющегося основанием системы счисления, в которой надо отобразить число.

puts (2**50).to_s puts (2**50).to_s(2) puts (2**50).to_s(16) puts (2**50).to_s(31)

1125899906842624

100000000000000000000000000000000000000000000000000

4000000000000

1bi31arsea1

Ситуация с вещественными числами во всех языках программиро• вания (и Ruby здесь не исключение) значительно сложнее. В отличии от целых чисел Z вещественные числа R обладают свойством полноты: между любыми двумя различными числами всегда найдется отличное от них третье. Понятно, что невозможно сохранить это свойство беско• нечного множества действительных чисел, как бы мы ни представляли их в виде конечного множества RM. Наиболее распространенным спо• собом реализации вещественных чисел является использование чисел с плавающей точкой. При этом множество RM оказывается состоящим

6

из элементов вида

f = ± αp1 + αp22 + . . . + αpnn pe,

где целые числа αi для любого i из диапазона от 1 до n удовлетворяют соотношению 0 6 αi 6 p − 1, а величина e, называемая экспонентой, лежит в диапазоне от L до U ( L 6 e 6 U). Число p является основани• ем системы счисления (чаще всего это 2), константа n задает точность представления чисел, а диапазон [L, U] определяет область значений экспоненты. Число ± αp1 + αp22 + . . . + αpnn принято называть мантиссой числа f с плавающей точкой.

Множество RM симметрично относительно начала координат; нуль принадлежит нашему множеству, Ближайшая к нулю положительная точка получается при α1 = 1, α2 = . . . = αn = 0, e = L; т.е. в двоичной системе счисления задается формулой fmin = 12 · 2L.

В языке Ruby наименьшее из положительных чисел класса Float представляется константой MIN, максимальное — константой MAX, зна• чения L и U задаются константами MIN_EXP и MAX_EXP соответственно, а число n — константой DIG:

puts Float::MIN puts Float::MAX puts Float::MAX_EXP puts Float::MIN_EXP puts Float::DIG

2.2250738585072e-308

1.79769313486232e+308

1024 -1021 15

Убедимся, что величина константы MIN совпадает со значением fmin:

puts Float::MIN

puts 0.5*2**Float::MIN_EXP

2.2250738585072e-308

2.2250738585072e-308

Кроме вышеперечисленных констант в классе Float определена ещё одна — EPSILON, она определяется из условия, что величина EPSILON есть наименьшее из всех x, таких что 1.0 + x 6= 1.0.

§ 2. Базовые классы

7

puts Float::EPSILON

2.22044604925031e-16

Для чисел определены стандартные арифметические операции: +, -, *, /, ** (возведение в степень). Кроме этого на множестве целых чисел определена операция деления по модулю % (получение остатка от деления). Обратите особое внимание на то, что если оба аргумента оператора / являются экземплярами класса Integer, то и результат операции будет экземпляром того же класса.

puts 2**100 # => 1267650600228229401496703205376 puts 35/6 # => 5

puts 12%8 # => 4

Строки

Строки — представители класса String. Строки заключаются ли• бо одинарными ’, либо двойными " кавычками. Однако такие строки имеют различия между собой. При использовании двойных кавычек допускается вставлять в строки управляющие escape-последователь• ности, начинающиеся с символа \, а также вычислять выражения с помощью конструкции #{}.

print "\n" # => print ’\n’ # => \n

print "\tHello","\n" # => Hello print ’\tHello’,"\n" # =>\tHello puts "5*3 = #{5*3}" # => 5*3 = 15 puts ’5*3 = #{5*3}’ # => 5*3 = #{5*3}

Ruby содержит огромное количество методов для работы со строка• ми. Мы не будем перечислять их, так как язык Ruby позволяет узнать полный список методов, доступных для экземпляра (instance) того или иного класса при помощи метода instance_methods, например,

puts String.instance_methods

Дата и время

Класс Time предназначен для работы с датами и временем. Метод now возвращает текущее время, метод local позволяет создать экзем• пляр класса с заданной датой и временем ( первый аргумент — год —

8

обязателен, остальные аргументы можно не указывать). Среди боль• шого количества доступных методов отметим только yday, wday, year, month и его синоним mon, day и его синоним mday, hour, min, sec, to_i

(число секунд, прошедших с 1 января 1970 года).

Следующий пример позволяет определить количество дней, остав• шихся до Нового года.

puts (Time.local(2005, 12, 31).yday - \ Time.now.yday)

Другие классы

Список всех классов можно получить с помощью такой инструкции

ObjectSpace.each_object( Class ){|cl| p cl.name}

Упражнения

1.Напечатайте таблицу истинности для операции импликации A B.

2.Напечатайте представление числа 778 в двоичной системе счисле• ния.

§ 3. Советы начинающим

Название функций и переменных

Всегда давайте осмысленные имена переменным, функциям (проце• дурам) и классам. Правильный стиль в оформлении названий таков — имена переменных и функций следует писать с маленькой буквы, в слу• чае когда название состоит из нескольких слов их следует соединять при помощи символа подчеркивание «_».

def distance(x1, y1, x2, y2) Math.sqrt((x2-x1)**2 + (y2-y1)**2)

end

def print_details(number) if number % 2 == 0

puts " Число #{number} - четное " else

puts " Число #{number} - нечетное " end

§ 3. Советы начинающим

9

end

Константы (т. е. величины, которые не должны изменяться в про• цессе выполнения программы) следует обозначать большими буквами, используя для разделения слов символ подчеркивания:

PI = 3.14

DEG_2_RAD = PI/180

Имена классов обязаны начинаться с заглавной буквы. Раздели• телем слов в названии служит поставленная в начале слова большая буква.

class BasePoint

...

end

class Convex

...

end

Но самое главное — это давать осмысленные имена, прочитав которые легко понять за что отвечает и для чего предназначен тот или иной класс, функция или переменная.

#плохой стиль axz = 100

ab = (axz % 2 == 0)

#хороший стиль

num = 100

is_even_num = (num % 2 == 0)

Дублирование кода

Дублирование кода возникает когда один и тот же кусок програм• мы присутствует в двух функциях или, что часто встречается у начи• нающих, внутри одной. Очевидно, что если их удастся объединить, то программа от этого только выиграет. Все что нужно сделать — это «вытащить» повторяющуюся часть программы в отдельную функцию и вызвать созданную функцию из точек повторения. Приведем пример программы с дублированием кода.

#Для введённого чётного числа напечатать его представление

#в виде суммы двух простых чисел или фразу "нет разбиения",

10

# если такого представления не существует.

def number_decomposition(num) simple_1, simple_2 = num/2, num/2

while simple_1 > 1 and simple_2 < num is_simple_1, is_simple_2 = true, true i = 2

while i < simple_1

if simple_1 % i == 0 is_simple_1 = false break

end

i += 1 end

k = 2

while k < simple_2

if simple_2 % k == 0 is_simple_2 = false break

end

k += 1 end

if is_simple_1 and is_simple_2

puts "", "#{simple_1} + #{simple_2} = #{num}" return

end

simple_1 -= 1 simple_2 += 1

end

puts "нет разбиения" end

print "Введите шётное число:"; num = gets.to_i number_decomposition(num)

Немного посмотрев на пример легко обнаружить, что в процеду• ре содержаться два повторяющихся фрагмента кода отвечающих за определение простоты числа. Вынесем повторяющийся код в отдель•

Соседние файлы в папке Ruby