Вторая лекция по основам ruby для студентов itc73.ru

Preview:

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

Recommended