Таймкоды
4:12 — описание работы инструмента jupyter
7:30 — особенности передачи параметров в методы
13:45 — классы
14:21 — именование переменных
14:51 — разбор программы, выводящей связь предок-потомок в древеобразной форме
20:52 — конструкторы
24:41 — атрибуты
30:50 — пространство объектов
32:44 — класс Struct
34:59 — наследование
36:02 — доступ к метаданным
38:01 — управление доступом
42:44 — «замораживание» объекта методом freeze
45:14 — константы
48:04 — распределенное объявление и переопределение классов
53:03 — видимость атрибутов
57:18 — определение методов на русском языке
58:21 — класс Module
1:00:41 — примеси (mixins)
1:04:10 — сравнение Enumerator и Enumerable
1:06:33 — класс Enumerator
1:12:18 — класс Enumerable
1:14:37 — динамическое выполнение кода
1:18:22 — тестирование через построение дерева
1:20:27 — тестирование с помощью тестовых наборов
1:21:37 — автоматические тесты
1:26:44 — отладка Ruby-программ
1:29:48 — статическая проверка кода
1:32:39 — Ruby Version Manager (RVM)
Параметры
*x — как параметр обозначает не ограниченное кол-во аргументов
**x — не ограниченное кол-во аргументов, но для ключевого слова аргументов. Будет хеш вместо массива
def testing(a, b = 1, *c, d: 1, **x)
p a,b,c,d,x
end
testing('a', 'b', 'c', 'd', 'e', d: 2, x: 1)
Code language: JavaScript (javascript)
- * — как параметр обозначает взять все аргументы
def print_all(*)
end
Это означает, что метод принимает любые аргументы, но ничего с ними не делает. Это похоже на использование символа подчеркивания (_) внутри блока, чтобы показать, какие аргументы вы не используете.
На практике это может быть в сочетании с ключевым словом super:
class Food
def nutrition(vitamins, minerals)
puts vitamins
puts minerals
end
end
class Bacon < Food
def nutrition(*)
super
end
end
bacon = Bacon.new
Code language: JavaScript (javascript)
Проверка сцепленных опператоров. Save navigation operator(&.)
После руби 2.3
if account&.owner&.address
...
end
Code language: CSS (css)
Классы
class Color
def initialize(r,g,b,s1,s2)
@r, @g, @b, @s1, @s2 = r,g,b,s1,s2
end
def self.while(s1,s2)
new(000, 000, 000, s1, s2) # Указали первые 3 значения для конструктора. И перезаписали метод new
end
def inspect
"#{@r}, #{@g}, #{@b}, #{@s1}, #{@s2}" # Презаписали вывод для 'p' в более удобный вид
end
end
b = Color.while(13,234)
p b
# 0, 0, 0, 13, 234
Code language: CSS (css)
class Metal
@@current_temp = 70
attr_accessor :atomic_number
def Metal.current_temp=(x)
@@current_temp = x
end
def Metal.current_temp
@@current_temp
end
def liquid?
@@current_temp >= @melting
end
def initialize(atnim, melt)
@atomic_number = atnim
@melting = melt
end
end
alum = Metal.new(60, 1340)
gold = Metal.new(79, 1984)
p alum.liquid?
p gold.liquid?
Metal.current_temp = 1982
p alum.liquid?
p gold.liquid?
# false
# false
# true
# false
Code language: CSS (css)
Класс Struct
Применяется для сокращения записи при создании класса
attr_reader с атрибутами объявляется не явно
Student = Struct.new(:fname, :name)
stud = Student.new("Pavel", "Pestau")
p Student.class
p stud.class
puts "Студ #{stud.fname} #{stud.name}"
Code language: Ruby (ruby)
Управление доступом в классе
- Public — общедоступные методы (можем не писать)
- Protected — только для класса и потомков
- Private — только для методов класса
Внимание! Мы можем ограничивать доступ не только для методов но и для аттрибутов, например программа которая сравнивает возраст пользователей, не позволяет прочитать его (возраст)
class Person
def initialize(name, age)
@name, @age = name, age
end
def <=> (other)
age <=> other.age
end
attr_reader :name, :age # Определяем аттрибуты
protected :age # закроем возраст для доступа
end
p1 = Person.new('Fred', 31)
p2 = Person.new('Max', 20)
p (p1 <=> p2) # 1
p p2.age # protected method `age' called for #<Person:0x0
Code language: Ruby (ruby)
Freeze. Особенности работы
Есть строка, применили freeze и добавили сложение с другой строкой, по идее значение переменной не должно меняться, однако оно измениться.
На самом деле мы не изменили объект, а создали ссылку на новый и присвоили ее нашей переменной.
Что же делать? — Использовать константы. Константа позволяет заблокировать изменение ссылки в переменной на который она ссылается. Теперь если мы применим freeze все будет работать
Переопределение методов в стандартных классах
class Time
def to_s
strftime '%H:%M:%S %d.%m'
end
def inspect
print "Метод инспект был перезаписан"
end
end
puts Time.now
p Time.now
# 16:46:40 01.09
# Метод иснпект был перезаписан
Code language: Ruby (ruby)
Выполнение кода из строки и из внешнего файла методами Eval и load(‘file.rb’, true)
Тестировние дерева
class Tree
attr_accessor :left, :right, :data
protected :left, :right, :data
def initialize(x = nil)
@left, @right, @data = nil, nil, x
end
def insert(x)
if @data.nil?
@data = x
elsif x <= @data
@left ? @left.insert(x) : @left = Tree.new(x)
else
@right ? @right.insert(x) : @right = Tree.new(x)
end
end
def inorder
@left.inorder { |y| yield y } unless @left.nil?
yield @data
@right.inorder { |y| yield y } unless @right.nil?
end
def inbackorder
@right.inbackorder { |y| yield y } unless @right.nil?
yield @data
@left.inbackorder { |y| yield y } unless @left.nil?
end
end
items = [1,5,6,3,2,8,7,4,9]
# или items = gets.split.map(&:to_i)
# или items = Array.new(14){ rand(100)-50 }
tree = Tree.new
items.each { |x| tree.insert(x) }
puts tree.inorder { |x| print "#{x} "}
puts tree.inbackorder { |x| print "#{x} "}
Code language: Ruby (ruby)
require './z.rb' # Путь к файлу
require 'minitest/autorun'
class TestTree < MiniTest::Unit::TestCase
def setup # вызывается перед выполнением каждого теста
#@items = [35, 1, 24, 2, -4, 3, 25, 4, 94, 5, 0, 6, 14, 7]
@items = Array.new(100) { rand(200) - 100 }
#@items = 100.times.map { Random.rand(200) - 100 }
@tree = Tree.new
@items.each { |x| @tree.insert(x) }
@result = [ ]
end
def test_1
@tree.inorder { |x| print "#{x} "; @result << x } # формируем результат assert_equal(@items.sort, @result) # сравниваем c эталоном
end
def test_2
@tree.inbackorder { |x| print "#{x} "; @result << x } # формируем результат assert_equal(@items.sort_by { |x| -x }, @result ) # сравниваем c эталоном
end
end
Code language: Ruby (ruby)