Upload
alexander-shcherbinin
View
1.534
Download
1
Embed Size (px)
Citation preview
RubyОсновы
Типы данных
Типы данных
Типы данныхNumeric
123 # экземпляр класса Fixnum1000000000 # один миллиард1_000_000_000 # один миллиард
0377 # восьмеричное представление числа 2550b1111_1111 # двоичное представление числа 2550xFF # шестнадцатеричное представление числа 255
0.0 # экземпляр класса Float-3.14 # экземпляр класса Float6.02e23 # экземпляр класса Float (6.02 * 10^23)
Типы данныхNumeric
x = 5/2 # => 2y = 5.0/2 # => 2.5z = 5/2.0 # => 2.5x = 5%2 # => 1x = 1.5%0.4 # => 0.3
2**4 # 16# вычисляется справа налево2**4**3 # равно 2**64, но не 16**3
арифметика:
Типы данныхString
'string' # строка"string" # строка
# строковой литерал в двойных кавычках может включать ruby-выраженияphone = "55-66-77""my phone is #{phone}"$phone = "55-66-77""my phone is #$phone" # с глобальными переменными, # переменными экземпляра и класса # {} можно опустить
Типы данныхString
# ruby-строки мутабельны (mutable, изменчивы)# на каждое появление строкового литерала в коде программы# создается новый объект# поэтому крайне нежелательно использование строк в циклах5.times { puts "test".object_id }
# используйте символы5.times { puts :test.object_id }
Типы данныхArray
[] # пустой массив[1, 2, 3] # массив из трех объектов Fixnum[[1,2], [3,4]] # массив из вложенных массивовArray.new # => []Array.new(3) # => [nil, nil, nil]Array.new(3, 1) # => [1, 1, 1]
Типы данныхArray
a = [0, 1, 4, 9, 16]a[0] # => 0a[-1] # => 16a[8] = 64 # => [0, 1, 4, 9, 16, nil, nil, nil, 64]a[1, 1] # => [1]a[1, 2] # => [1, 4]a[0..2] # => [0, 1, 4]
Типы данныхHash
numbers = Hash.newnumbers["one"] = 1numbers["two"] = 2numbers["three"] = 3sum = numbers["one"] + numbers["two"]
numbers = {"one" => 1, "two" => 2, "three" => 3}numbers = {:one => 1, :two => 2, :three => 3}# only ruby 1.9numbers = {one: 1, two: 2, three: 3}
Типы данныхRange
1..10 # числа от 1 до 10, включая 101.0...10.0 # числа от 1.0 до 10.0, исключая 10.0a = 1..10a.include? 5 # => true: 5 входит в диапазон [1,5]'a'..'d' # буквы от a до d('a'..'d').to_a # => ['a', 'b', 'c', 'd']
Типы данныхNilClass, TrueClass, FalseClass
nil.class # => NilClassfalse.class # => FalseClasstrue.class # => TrueClass
единственные экземпляры своих классов:
Объекты
• в ruby все - объект
• вся работа происходит со ссылками на объекты (все, кроме Fixnum и Symbol передается по ссылке)
• каждый объект имеет свой уникальный и неизменный идентификатор (object_id)
Объекты
o = "test" # создаем новую переменнуюo.class # => Stringo.class.superclass # => Objecto.class == String # => trueo.instance_of? String # => true
Объекты
x = 1x.instance_of? Fixnum # => truex.instance_of? Numeric # => false: instance_of? # не проверяет наследственностьx.is_a? Fixnum # => truex.is_a? Numeric # => truex.is_a? Integer # => truex.is_a? Comparable # => true: is_a? работает # и с миксинамиNumeric === x # => true: идентично is_a? # но менее элегантно
Объекты
Однако, в ruby принято обращать внимание не на класс объекта, а на его тип
Тип объекта - это совокупность его признаков, а не только его класс
Объекты
типизация по общим признакам объекта носит название "утиной":
если это выглядит как утка, плавает как утка и крякает как утка, то, вероятно, это утка
Обычно считается, что объект принадлежит какому-то типу, если относительно него можно провести некие определенные действия (вызвать определенные методы)
o.respond_to? :each # результат true, если o обладает # методом each
Объекты
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: строгая проверка
сравнение объектов
Структура программыЛексическая, Синтаксическая, Структура файла
Лексическая структура.Комментарии
# это комментарийx = "# а это строка"y = /# а это регулярное выражение/ # а вот здесь уже комментарий
# а так принято# писать многострочные комментарии# в ruby нет многострочных комментариев like a C /*..*/
=begin а еще можно закомментировать опасный участок кода при помощи такого комментария такой стиль комментариев называется "Встроенный документ" и он не очень популярен в ruby=end
Лексическая структура.Комментарии
Лексическая структура.Идентификаторы и пунктуация
• Идентификатор - имя (переменные, методы, классы, модули, и т.д.)
• состоят из букв, цифр и символов подчеркивания• не могут начинаться с цифр• идентификатор, начинающийся с заглавной буквы является константой
• чувствительны к регистру
Лексическая структура.Идентификаторы и пунктуация
ab2new_value_temp PI # константа
$files # глобальная переменная@data # переменная экземпляра@@counter # переменная классаempty? # метод/предикат, возвращающий булево значениеsort! # метод, изменяющий объектtimeout= # метод, вызываемый присваиванием
Лексическая структура.Ключевые слова
__LINE__
__ENCODING__
__FILE__
BEGIN
END
alias
and
begin
break
case
class
def
defined?
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
then
true
undef
unless
until
when
while
yield
Лексическая структура.Разделители
• как и в Си точка с запятой является символом конца оператора
• однако, в ruby символ новой строки так же признак конца оператора
• по соглашению, “;” обычно опускается
Лексическая структура.Разделители
total = thirst_very_long_name + second_long_name \ + third_long_name
“нейтрализовать” конец строки можно символом “\”
Лексическая структура.Разделители
• ruby позволяет опускать скобки при вызовах/объявлениях методов
• однако, нужно быть аккуратным с пробелами:
f(3+2)+1 # сумма f(3+2) и 1f (3+2)+1 # вызов f от выражения (3+2)+1
Синтаксическая структураВыражения
• Выражение - основной элемент синтаксиса Ruby
• простейшие выражения - числовые и строковые литералы
• выражения вычисляются интерпретатором и выдают значение
• могут строиться составные выражения при помощи знаком операций
Синтаксическая структураВыражения
1 # первичное выражениеx # еще одно первичное выражениеx = 1 # выражение присваиванияx = x + 1 # выражение с двумя знаками операций
Синтаксическая структураВыражения
if 10 > 1 then # здесь "then" можно и принято опускать x += 1end
while x < 10 do print x x = x + 1end
3.times do |n| # do/end можно заменить на скобки {} print "step #{n}" # вариант со скобками принято # использовать в однострочных конструкциях:end # 3.times {|n| print "step #{n}"}
Синтаксическая структураПеременные
• Переменная - просто имя для значения• создание переменной приходит при помощи оператора присваивания: (x = 2.0)
Синтаксическая структураПеременные
• переменная класса: ошибка NameError
• переменная экземпляра: вернет nil
• глобальная переменная: вернет nil
• локальная переменная: в большинстве случаев выдаст ошибку NameError
Вызов неинициализированное переменной:
Синтаксическая структураПеременные
a = 0.0 if false # присваивание никогда не выполнитсяprint a # выводится nilprint b # NameError: переменной или метода b # никогда не существовало
Синтаксическая структураКонстанты
• Имя константы начинается с заглавной буквы
• название класса/модуля - тоже константа• константа на самом деле не константа (может меняться)
• нельзя присвоить значение константе в теле метода
Синтаксическая структураКонстанты
SomeConstant # модуль или классSOME_CONSTANT # константаSome_Constant # константа
соглашение:
Синтаксическая структураКонстанты
Conversions::Area # константы могут быть вложеннымиArea # внутри модуля Conversions # вычислится в Conversions::Area::Area # а так будет искаться # в глобальной области видимости (Object)Object::Area # идентично ::Area
Синтаксическая структураМетоды
# объявлениеdef my_method(arg1, arg2, arg3 = nil) # скобки можно опустить # возвращает последнее вычисленное значениеend
# вызовmy_method 1, 2, :limit => 10
Синтаксическая структураПрисваивания
# обычное присваивание (вызов сеттера)o.m = v# фактически вызов метода:o.m=(v)
# присваивание в массивахo[x] = y# эквивалентноo.[]=(x, y)
# метод []= можно написать самому, например, с целью:o[x, y] = z# эквивалентноo.[]=(x,y,z)
Синтаксическая структураПрисваивания
# сокращенные присваиванияx += y # x = x + y (следует заметить, в ruby нет # инкремента через x++)x -= y # x = x - yx /= y # x = x / yx %= y # x = x % yx **= y # x = x ** yx &&= y # x = x && yx ||= y # x = x || yx &= y # x = x & yx |= y # x = x | yx ^= y # x = x ^ yx <<= y # x = x << yx >>= y # x = x >> y
Синтаксическая структураПрисваивания
# параллельное присваивание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]
Синтаксическая структураПрисваивания
results ||= []results = results || []
идиома:
Синтаксическая структураОператоры
+
-
!
~
**
*
/
%
<<
>>
&
|
^
<
<=
>=
>
==
===
!=
=~
!~
<=>
&&
||
..
?:
rescue
=
**=
*=
/=
%=
+=
-=
<<=
>>=
&&=
&=
||=
|=
^=
defined?
not
and
or
if
unless
while
until
Синтаксическая структураОператоры
# унарные операторы: - и +x = -xx = +x # просто вернет x
# возведение в степеньx = 2 ** 3 # x => 8
# арифметические операторы: +, -, *, /, %x = 2 + 3y = 7 / 0 # выдаст ZeroDivisionErrorz = -5.0 / 0 # вернет -Infinity
Синтаксическая структураОператоры
# сдвиг и добавление: << и >># сдвиг битов:(0b1011 << 1).to_s(2) # => "10110", 11 << 1 => 22# чаще используется как добавлениеmessage = "hello"message << " world"messages = []messages << message
Синтаксическая структураОператоры
# сравнение: <, <=, >, >=, <=>1 < 2 # => true3 >= 3 # => true4 <=> 2 # => 1 (-1 если меньше; 0 если равны; 1 если больше)
class A; endclass B < A; endA < B # => false
String < Object # => true: String более узкий классObject > Numeric # => true: Object более общий классNumeric < Integer # => false: Numeric не является # более узким, чем IntegerString < Numeric # => nil: String и Numeric никак не связаны
Синтаксическая структураОператоры
# равенство: ==, !=, =~, !~, ===1 == 2 # => false2 != 3 # => true"message" =~ /e/ # => 1: позиция первого вхождения # символа e согласно регулярке5 === 5 # => true(1..5) === 5 # => true: case-равенство
Синтаксическая структураОператоры
# условный оператор: ?:a = b > c ? true : false
# defined?# проверяет, определен ли его операнд# пример использования:y = f(x) if defined? f(x)
Структура файла
#!/bin/ruby -w# encoding: utf-8
# code#__END__
# another data
shebang-комментарийкодировка программы
код программы
маркировка завершения кода
другие данные программы
Выполнение программы
• ruby-программа - простой сценарий из операторов
• исполнение программы происходит последовательно, в порядк обнаружения операторов
• управляющие структуры (условия, циклы, и т.д.) влияют на порядок исполнения операторов
• простейший запуск ruby программы выглядит как “ruby file.rb”
Управляющие структуры
Управляющие структурыif
if x < 10 x += 1else print xend
Управляющие структурыif
name = if x == 1; "один" elsif x == 2; "два" elsif x == 3; "три" else "много" end
puts message if message # модификатор if
if x == 1 name = "один"elsif x == 2 name = "два"elsif x == 3 name = "три"end
Управляющие структурыunless
s = unless o.nil? o.to_s end
s = o.to_s unless o.nil? # модификатор unless
• противоположен if• нет конструкции elsif
Управляющие структурыcase
name = case when x == 1 "один" when x == 2 "два" when x == 3 "три"end
name = case x when 1; "один" when 2; "два" when 3; "три" else "много"end
Управляющие структурыwhile/until
x = 10while x >= 0 do puts x x -= 1end
x = 0until x > 10 do puts x x += 1end
Управляющие структурыwhile/until
x = 0 # инстанцирование xputs x = x + 1 while x < 10 # увеличение x на 1 пока x < 10
a = [1, 2, 3] # инициализация массиваputs a.pop until a.empty? # извлечение элементов, пока # массив не пустой
Управляющие структурыfor-in
array = [1, 2, 3, 4, 5]for element in array puts elementend
hash = {:a => 1, :b => 2, :c => 3}for key, value in hash puts "#{key} => #{value}"end
Управляющие структурыfor-in
# использование итератора вместо for-inarray.each do |value| puts valueend
hash.each do |key, value| puts "#{key} => #{value}"end
Управляющие структурыrescue/ensure
begin raise "Error!" # бросаем исключениеrescue => e # обработка исключения p eensure # блок выполнится всегда print "все равно выполнится"end