4. Типы данных
Numeric
123 # экземпляр класса Fixnum
1000000000 # один миллиард
1_000_000_000 # один миллиард
0377 # восьмеричное представление числа 255
0b1111_1111 # двоичное представление числа 255
0xFF # шестнадцатеричное представление числа 255
0.0 # экземпляр класса Float
-3.14 # экземпляр класса Float
6.02e23 # экземпляр класса Float (6.02 * 10^23)
5. Типы данных
Numeric
арифметика:
x = 5/2 # => 2
y = 5.0/2 # => 2.5
z = 5/2.0 # => 2.5
x = 5%2 # => 1
x = 1.5%0.4 # => 0.3
2**4 # 16
# вычисляется справа налево
2**4**3 # равно 2**64, но не 16**3
6. Типы данных
String
'string' # строка
"string" # строка
# строковой литерал в двойных кавычках может включать ruby-
выражения
phone = "55-66-77"
"my phone is #{phone}"
$phone = "55-66-77"
"my phone is #$phone" # с глобальными переменными,
# переменными экземпляра и класса
# {} можно опустить
7. Типы данных
String
# ruby-строки мутабельны (mutable, изменчивы)
# на каждое появление строкового литерала в коде
программы
# создается новый объект
# поэтому крайне нежелательно использование строк
в циклах
5.times { puts "test".object_id }
# используйте символы
5.times { puts :test.object_id }
8. Типы данных
Array
[] # пустой массив
[1, 2, 3] # массив из трех объектов Fixnum
[[1,2], [3,4]] # массив из вложенных массивов
Array.new # => []
Array.new(3) # => [nil, nil, nil]
Array.new(3, 1) # => [1, 1, 1]
11. Типы данных
Range
1..10 # числа от 1 до 10, включая 10
1.0...10.0 # числа от 1.0 до 10.0, исключая 10.0
a = 1..10
a.include? 5 # => true: 5 входит в диапазон [1,5]
'a'..'d' # буквы от a до d
('a'..'d').to_a # => ['a', 'b', 'c', 'd']
13. Объекты
• в ruby все - объект
• вся работа происходит со ссылками на объекты
(все, кроме Fixnum и Symbol передается по
ссылке)
• каждый объект имеет свой уникальный и
неизменный идентификатор (object_id)
14. Объекты
o = "test" # создаем новую переменную
o.class # => String
o.class.superclass # => Object
o.class == String # => true
o.instance_of? String # => true
15. Объекты
x = 1
x.instance_of? Fixnum # => true
x.instance_of? Numeric # => false: instance_of?
# не проверяет наследственность
x.is_a? Fixnum # => true
x.is_a? Numeric # => true
x.is_a? Integer # => true
x.is_a? Comparable # => true: is_a? работает
# и с миксинами
Numeric === x # => true: идентично is_a?
# но менее элегантно
16. Объекты
Однако, в ruby принято обращать внимание не на
класс объекта, а на его тип
Тип объекта - это совокупность его признаков, а не
только его класс
17. Объекты
Обычно считается, что объект принадлежит какому-то
типу, если относительно него можно провести некие
определенные действия (вызвать определенные методы)
o.respond_to? :each # результат true, если o обладает
# методом each
типизация по общим признакам объекта носит
название "утиной":
если это выглядит как утка, плавает как утка и
крякает как утка, то, вероятно, это утка
18. Объекты
сравнение объектов
a = "ruby"
b = c = "ruby"
a.equal?(b) # => false: a и b относятся к разным объектам
b.equal?(c) # => true: b и c ссылаются на один объект
b.object_id == c.object_id
a == b # => true: проверка по содержимому объекта
1 == 1.0 # true: в классах Numeric используется
# преобразование типов
1.eql?(1.0) # false: строгая проверка
20. Лексическая структура.
Комментарии
# это комментарий
x = "# а это строка"
y = /# а это регулярное выражение/ # а вот здесь уже
комментарий
# а так принято
# писать многострочные комментарии
# в ruby нет многострочных комментариев like a C /*..*/
21. Лексическая структура.
Комментарии
=begin а еще можно закомментировать
опасный участок кода
при помощи такого комментария
такой стиль комментариев называется "Встроенный документ"
и он не очень популярен в ruby
=end
22. Лексическая структура.
Идентификаторы и пунктуация
• Идентификатор - имя (переменные, методы,
классы, модули, и т.д.)
• состоят из букв, цифр и символов подчеркивания
• не могут начинаться с цифр
• идентификатор, начинающийся с заглавной буквы
является константой
• чувствительны к регистру
23. Лексическая структура.
Идентификаторы и пунктуация
a
b2
new_value
_temp
PI # константа
$files # глобальная переменная
@data # переменная экземпляра
@@counter # переменная класса
empty? # метод/предикат, возвращающий булево значение
sort! # метод, изменяющий объект
timeout= # метод, вызываемый присваиванием
24. Лексическая структура.
Ключевые слова
__LINE__ do
or
__ENCODING__ else
redo
__FILE__ elsif
rescue
BEGIN end
retry
END ensure
then
alias false
true
and for
undef
begin if
unless
break in
until
case module
when
class next
while
def nil
yield
defined? not
25. Лексическая структура.
Разделители
• как и в Си точка с запятой является символом
конца оператора
• однако, в ruby символ новой строки так же
признак конца оператора
• по соглашению, “;” обычно опускается
26. Лексическая структура.
Разделители
“нейтрализовать” конец строки можно символом “”
total = thirst_very_long_name + second_long_name
+ third_long_name
27. Лексическая структура.
Разделители
• ruby позволяет опускать скобки при вызовах/
объявлениях методов
• однако, нужно быть аккуратным с пробелами:
f(3+2)+1 # сумма f(3+2) и 1
f (3+2)+1 # вызов f от выражения (3+2)+1
28. Синтаксическая структура
Выражения
• Выражение - основной элемент синтаксиса Ruby
• простейшие выражения - числовые и строковые
литералы
• выражения вычисляются интерпретатором и
выдают значение
• могут строиться составные выражения при
помощи знаком операций
29. Синтаксическая структура
Выражения
1 # первичное выражение
x # еще одно первичное выражение
x = 1 # выражение присваивания
x = x + 1 # выражение с двумя знаками операций
30. Синтаксическая структура
Выражения
if 10 > 1 then # здесь "then" можно и принято опускать
x += 1
end
while x < 10 do
print x
x = x + 1
end
3.times do |n| # do/end можно заменить на скобки {}
print "step #{n}" # вариант со скобками принято
# использовать в однострочных конструкциях:
end # 3.times {|n| print "step #{n}"}
31. Синтаксическая структура
Переменные
• Переменная - просто имя для значения
• создание переменной приходит при помощи
оператора присваивания: (x = 2.0)
32. Синтаксическая структура
Переменные
Вызов неинициализированное переменной:
• переменная класса: ошибка NameError
• переменная экземпляра: вернет nil
• глобальная переменная: вернет nil
• локальная переменная: в большинстве
случаев выдаст ошибку NameError
33. Синтаксическая структура
Переменные
a = 0.0 if false # присваивание никогда не выполнится
print a # выводится nil
print b # NameError: переменной или метода b
# никогда не существовало
34. Синтаксическая структура
Константы
• Имя константы начинается с заглавной буквы
• название класса/модуля - тоже константа
• константа на самом деле не константа (может
меняться)
• нельзя присвоить значение константе в теле
метода
35. Синтаксическая структура
Константы
соглашение:
SomeConstant # модуль или класс
SOME_CONSTANT # константа
Some_Constant # константа
36. Синтаксическая структура
Константы
Conversions::Area # константы могут быть вложенными
Area # внутри модуля Conversions
# вычислится в Conversions::Area
::Area # а так будет искаться
# в глобальной области видимости (Object)
Object::Area # идентично ::Area
37. Синтаксическая структура
Методы
# объявление
def my_method(arg1, arg2, arg3 = nil) # скобки можно опустить
# возвращает последнее вычисленное значение
end
# вызов
my_method 1, 2, :limit => 10
38. Синтаксическая структура
Присваивания
# обычное присваивание (вызов сеттера)
o.m = v
# фактически вызов метода:
o.m=(v)
# присваивание в массивах
o[x] = y
# эквивалентно
o.[]=(x, y)
# метод []= можно написать самому, например, с целью:
o[x, y] = z
# эквивалентно
o.[]=(x,y,z)
39. Синтаксическая структура
Присваивания
# сокращенные присваивания
x += y # x = x + y (следует заметить, в ruby нет
# инкремента через x++)
x -= y # x = x - y
x /= y # x = x / y
x %= y # x = x % y
x **= y # x = x ** y
x &&= y # x = x && y
x ||= y # x = x || y
x &= y # x = x & y
x |= y # x = x | y
x ^= y # x = x ^ y
x <<= y # x = x << y
x >>= y # x = x >> y
40. Синтаксическая структура
Присваивания
# параллельное присваивание
x, y, z = 1, 2, 3 # x = 1; y = 2; z = 3
x, y = y, x # обмен значениями, параллельно
# не тоже самое, что:
x = y; y = x # здесь вызовы последовательны
x = 1, 2, 3 # x = [1, 2, 3]
x, y, z = [1, 2, 3] # x, y, z = 1, 2, 3
x, *y = 1, 2, 3 # x = 1; y = [2, 3]
42. Синтаксическая структура
Операторы
+ < ?:
- <= rescue ||=
! >= = |=
~ > **= ^=
** == *= defined?
* === /= not
/ != %= and
% =~ += or
<< !~ -= if
>> <=> <<= unless
& && >>= while
| || &&= until
^ .. &=
43. Синтаксическая структура
Операторы
# унарные операторы: - и +
x = -x
x = +x # просто вернет x
# возведение в степень
x = 2 ** 3 # x => 8
# арифметические операторы: +, -, *, /, %
x = 2 + 3
y = 7 / 0 # выдаст ZeroDivisionError
z = -5.0 / 0 # вернет -Infinity
44. Синтаксическая структура
Операторы
# сдвиг и добавление: << и >>
# сдвиг битов:
(0b1011 << 1).to_s(2) # => "10110", 11 << 1 => 22
# чаще используется как добавление
message = "hello"
message << " world"
messages = []
messages << message
45. Синтаксическая структура
Операторы
# сравнение: <, <=, >, >=, <=>
1 < 2 # => true
3 >= 3 # => true
4 <=> 2 # => 1 (-1 если меньше; 0 если равны; 1 если больше)
class A; end
class B < A; end
A < B # => false
String < Object # => true: String более узкий класс
Object > Numeric # => true: Object более общий класс
Numeric < Integer # => false: Numeric не является
# более узким, чем Integer
String < Numeric # => nil: String и Numeric никак не связаны
46. Синтаксическая структура
Операторы
# равенство: ==, !=, =~, !~, ===
1 == 2 # => false
2 != 3 # => true
"message" =~ /e/ # => 1: позиция первого вхождения
# символа e согласно регулярке
5 === 5 # => true
(1..5) === 5 # => true: case-равенство
47. Синтаксическая структура
Операторы
# условный оператор: ?:
a = b > c ? true : false
# defined?
# проверяет, определен ли его операнд
# пример использования:
y = f(x) if defined? f(x)
48. Структура файла
#!/bin/ruby -w shebang-комментарий
# encoding: utf-8 кодировка программы
# code
# код программы
__END__ маркировка завершения кода
# another data другие данные программы
49. Выполнение программы
• ruby-программа - простой сценарий из
операторов
• исполнение программы происходит
последовательно, в порядк обнаружения
операторов
• управляющие структуры (условия, циклы, и т.д.)
влияют на порядок исполнения операторов
• простейший запуск ruby программы выглядит как
“ruby file.rb”
52. Управляющие структуры
if
if x == 1
name = "один" name = if x == 1; "один"
elsif x == 2 elsif x == 2; "два"
name = "два" elsif x == 3; "три"
elsif x == 3 else "много"
name = "три" end
end
puts message if message # модификатор if
53. Управляющие структуры
unless
• противоположен if
• нет конструкции elsif
s = unless o.nil?
o.to_s
end
s = o.to_s unless o.nil? # модификатор unless
54. Управляющие структуры
case
name = case
when x == 1
"один"
when x == 2
"два"
when x == 3
"три"
end
name = case x
when 1; "один"
when 2; "два"
when 3; "три"
else "много"
end
55. Управляющие структуры
while/until
x = 10
while x >= 0 do
puts x
x -= 1
end
x = 0
until x > 10 do
puts x
x += 1
end
56. Управляющие структуры
while/until
x = 0 # инстанцирование x
puts x = x + 1 while x < 10 # увеличение x на 1 пока x < 10
a = [1, 2, 3] # инициализация массива
puts a.pop until a.empty? # извлечение элементов, пока
# массив не пустой
57. Управляющие структуры
for-in
array = [1, 2, 3, 4, 5]
for element in array
puts element
end
hash = {:a => 1, :b => 2, :c => 3}
for key, value in hash
puts "#{key} => #{value}"
end
58. Управляющие структуры
for-in
# использование итератора вместо for-in
array.each do |value|
puts value
end
hash.each do |key, value|
puts "#{key} => #{value}"
end
59. Управляющие структуры
rescue/ensure
begin
raise "Error!" # бросаем исключение
rescue => e # обработка исключения
p e
ensure # блок выполнится всегда
print "все равно выполнится"
end