Ruby-шпаргалка: изучить основы языка или вспомнить забытое
Небольшая Ruby-шпаргалка для начинающих и продолжающих с типами данных и основными конструкциями самого дружелюбного языка.
Ruby-шпаргалка по основам кодинга
- официальный сайт сообщества
- онлайн-интерпретатор
Комментарии
# однострочный some_useful_var = 42 another_useful_var = 7 # однострочный =begin блочный комментарий =end
Вывод значений в консоль
Для вывода массивов удобно использовать print, для всего остального – puts.
Переменные и константы
counter = 10 # локальная user_age = 30 # локальная $password = "qwerty" # глобальная PI = 3.14 # константа
Операция присваивания неявно возвращает значение, которое можно использовать.
puts number = 42 # => 42 # параллельное присваивание a = b = c = 42 # множественное присваивание a, b, c = 9, 8, 7
Обработка ошибок
begin raise NoMemoryError, 'Кончилась память' rescue NoMemoryError => exception_variable puts 'Ошибка NoMemoryError', exception_variable else puts 'Код отработал без ошибок' ensure puts 'Этот код выполнится в любом случае' end
Ruby-шпаргалка по типам данных
Числа
42.class # => Fixnum 999999999999999999999.class # => Bignum 999_999_999_999_999_999_999.class # => Bignum 3.6.class # => Float 45.23e2.class # => Float a = 42.to_s a.class # => String
Арифметические операции:
1 + 1 # => 2 8 - 1 # => 7 10 * 2 # => 20 35 / 5 # => 7 2 ** 5 # => 32
Многие функции сгруппированы в модуле Math:
Math.sqrt(64) # => 8.0 Math.log(8, 2) # => 3.0 Math.sin(Math::PI/2) # => 1.0
Строки
Строки относятся к классу String:
word = "интерполяцию"
string1 = 'допускает экранирование \', но не понимает \n других последовательностей'
string2 = "допускает\nлюбые\tуправляющие последовательности и #{word}"
string3 = %q[Экранирует "двойные" и 'одинарные' кавычки, но не понимает \n других последовательностей]
string4 = %Q[Экранирует "двойные" и 'одинарные' кавычки и допускает\nлюбые\tуправляющие последовательности и #{word}]
string5 = `ls -a` # команда ОС, выведет список файлов в каталоге
Строки можно складывать с другими строками и умножать.
"Brother " + "Louie " * 3 # => Brother Louie Louie Louie "Ответ на самый главный вопрос... " + 42 # => no implicit conversion of Fixnum into String (TypeError)
Встроенные документы
text = <<MARKER маркер может быть любым MARKER
Специальные значения
nil.class #=> NilClass true.class #=> TrueClass false.class #=> FalseClass
Символы
Тип данных, похожий на неизменяющиеся строки:
puts :authorized.class # => Symbol status = :authorized status == :authorized # => true status == 'authorized' # => false status == :guest # => false
Массивы
Массивы в Ruby относятся к классу Array и могут содержать элементы с разными типами данных. Индексация начинается с нуля.
Создание
my_array = [9, "eight", false, nil, 3.0] empty_array = Array.new(5) # => [nil, nil, nil, nil, nil] true_array = Array.new(5, true) # => [true, true, true, true, true]
Узнать длину массива:
my_array.length my_array.count my_array.size
Получение элементов
my_array[1] # => eight my_array.[] 1 # => eight my_array[3].class # => NilClass my_array[33].class # => NilClass my_array.at(4) # => 3.0 my_array[-3] # => false my_array.last # => 3.0 my_array.first # => 9
Получить диапазон элементов:
my_array[1, 2] # => ["eight", false] my_array[0..4] # => [9, "eight", false, nil, 3.0] my_array[0...4] # => [9, "eight", false, nil] my_array.values_at(1, 4, 1..2) # => ["eight", 3.0, "eight", false] my_array.take(3) # => [9, "eight", false]
Добавление
test_array = [42] # в конец test_array << 43 # => [42, 43] test_array.push(46) # => [42, 43, 46] # в начало test_array.unshift(41) # => [41, 42, 43, 46] # на любую позицию test_array.insert(3, 44, 45) # => [41, 42, 43, 44, 45, 46]
Удаление
new_array = [1, 2, 3, 3, 3, 4, 5, nil, nil, 6] # последнего элемента last = new_array.pop # => 6 print new_array # => [1, 2, 3, 3, 3, 4, 5, nil, nil] # первого элемента first = new_array.shift # => 1 print new_array # => [2, 3, 3, 3, 4, 5, nil, nil] # с указанной позиции item = new_array.delete_at(2) # => 3 print new_array # => [2, 3, 3, 4, 5, nil, nil] # удаление конкретного значения value = new_array.delete(3) # => 3 print new_array # => [2, 4, 5, nil, nil] # удаление nil array_compact = new_array.compact # без изменения исходного массива print array_compact # => [2, 4, 5] print new_array # => [2, 4, 5, nil, nil] array_compact = new_array.compact! # с изменением исходного массива print array_compact # => [2, 4, 5] print new_array # => [2, 4, 5] # удаление повторяющихся значений double_array = [2, 3, 4, 5, 3, 6, 7, 5, 5] uniq_array = double_array.uniq # => [2, 3, 4, 5, 6, 7]
Хеши
Структуры данных, состоящие из пар ключ-значение. В качестве ключа обычно выступает строка или символ (с версии 1.9):
hash = {'color' => 'green', 'number' => 5}
hash.keys #=> ['color', 'number']
#хеш с символьными ключами
symbol_hash = { key1: 'value1', key2: 'value2' }
#хеш со смешанными ключами
mixed_hash = { :key1 => 'value1', 'key2' => 'value2' }
Зная ключ, можно получить связанное с ним значение. Если указанного ключа нет, вернется nil.
hash['color'] #=> 'green' hash['number'] #=> 5 hash['nothing'] #=> nil
Логические выражения
2 == 1 # => false [1, 2, 3] == [1, 2, 3] # => true 1 != 1 # => false 2 != 1 # => true !true # => false !0 #=> false 1 < 10 # => true 1 > 10 # => false 2 <= 2 # => true 2 >= 2 # => true 1 <=> 1 # => 0, числа равны 1 <=> 2 # => -1, левое число меньше 2 <=> 1 # => 1, левое число больше
Ruby-шпаргалка по функциям
Управляющие конструкции
Условия
if и unless
if условие then # ... else # ... end unless условие then # ... else # ... end x = if a > 0 then b else c end x = unless a <= 0 then b else c end
case
period = 2.3
case period
when 0
puts "Beginner"
when 0..1
puts "Junior"
when 1..3
puts "Middle"
when 3..6
puts "Senior"
else
puts "Super!"
end
Циклы
while и until
counter = 1
while counter <= 5
puts "итерация #{counter}"
counter += 1
end
counter = 0
until counter == 5
puts "значение счетчика #{counter}"
counter += 1
end
for
for counter in 1..5
puts "итерация #{counter}"
end
Вместо цикла for в Ruby удобнее применять итераторы.
Итераторы
Методы чисел
# 3 итерации
3.times do |i|
puts "итерация #{i}"
end
# от 0 до 3
0.upto(3) { |i| puts "значение счетчика #{i}" }
each
Метод each можно вызвать для массива, хеша или диапазона значений. Он принимает блок кода, который будет выполнен для каждого элемента.
(1..5).each do |counter|
puts "итерация #{counter}"
end
(1..5).each { |counter| puts "итерация #{counter}" }
[1, 2, 3].each { |element| puts "Элемент #{element}" }
{ "age": 18, "name": "John" }.each do |key, value|
puts "Свойство #{key} имеет значение #{value}"
end
Вариация метода each для учета индексов в массиве – each_with_index:
["крокодилы", "бегемоты", "обезьяны", "кашалоты"].each_with_index do |element, index|
puts "№ #{index} - #{element}"
end
Другие перебирающие методы
# получение суммы всех элементов
(5..10).reduce(:+) # => 45
(5..10).inject { |sum, n| sum + n } # => 45
# создание массива
(1..4).map { |i| i*i } # => [1, 4, 9, 16]
(1..4).collect { "cat" } # => ["cat", "cat", "cat", "cat"]
Обо всех доступных методах перечисляемых объектов (enumerable) можно прочитать в документации.
Функции
Функции всегда возвращают значение последнего вычисленного выражения. При вызове можно не использовать скобки, если выражение однозначно. Параметры разделяются запятой.
def double(x) x*2 # значение этого выражения будет возвращено end double(2) # => 4 double 3 # => 6 double double 4 # => 16 def sum(x, y) x + y end sum 3, 4 # => 7 sum sum(3, 4), 5 # => 12
Чтобы собрать список параметров в один массив, используется splat-оператор (*).
def foo(*array)
print array
end
foo("arg1", 2, false) # => ["arg1", 2, false]
Оператор yield позволяет передать внутрь функции любой блок кода.
def surround
puts "{"
yield
puts "}"
end
surround { puts 'hello world' }
# => {
# => hello world
# => }
Ruby-шпаргалка по классам
Классы объявляются с помощью ключевого слова class, принадлежат к типу Class, а их имена являются глобальными константами.
# ключевое слово class class Human end Human.class # => Class
Переменные
- Переменные класса начинаются с
@@. - Переменные экземпляров – с
@.
Доступ к переменным возможен только через методы. Можно создавать геттеры и сеттеры вручную или воспользоваться встроенными акцессорами:
class Human
@@species = "H.sapiens" # переменная класса
NAME = "Human Class" # константа класса
def initialize(name, age=0)
@name = name # переменная экземпляра
@age = age
end
def species # геттер для переменной класса
@@species
end
def name=(name) # сеттер для @name
@name = name
end
def name # геттер для @name
@name
end
attr_reader :name, :age # геттеры можно задать так
attr_writer :name, :age # а сеттеры так
attr_accessor :name, :age # или все сразу
end
Методы
Модификаторы:
public;private;protected.
Модификатор влияет на все перечисленные или объявленные после него методы.
Методы класса должны начинаться с self. Вызвать их можно только из самого класса.
class Human
# ...
def self.say(message) # метод класса
puts "#{message}"
end
def method1
# ...
end
def method2
# ...
end
def method3
# ...
end
private :method1, :method2 # приватные методы
protected :method3 # защищенный метод
public # все нижележащие методы публичные
def method4
# ...
end
end
Экземпляры классов
john = Human.new("John Dow", 30)
john.species # => "H. sapiens"
john.name # => "John Doe"
john.name = "John William Doe"
john.name # => "John William Doe"
Human.say("Hello") # => "Hello"
Наследование
Класс-наследник получает доступ ко всем методам и переменным класса родителя. Методы родителя могут перекрываться одноименными методами наследника. Но к ним можно обратиться с помощью ключевого слова super.
class Doctor < Human
def examinePatient # собственный метод класса
# ...
end
def method1 # метод перекрывает родительский
super.method1()
# ...
end
end
doc = Doctor.new("Gregory House")
puts doc.species # H. Sapiens, переменная класса-родителя
Множественное наследование в Ruby отсутствует, вместо него следует использовать примеси.
Модули
Модули в Ruby очень похожи на классы, но не могут наследоваться или создавать экземпляры. Их используют в основном для создания примесей или пространств имен.
module ModuleExample
def foo
'foo'
end
end
Если подключить модуль с помощью include, его методы добавятся экземплярам класса. Если воспользоваться оператором extend – самому классу.
class Person include ModuleExample end class Book extend ModuleExample end Person.foo # => NoMethodError: undefined method `foo' for Person:Class Person.new.foo # => 'foo' Book.foo # => 'foo' Book.new.foo # => NoMethodError: undefined method `foo'
Полезные ресурсы
-
- Программирование на языке Ruby, Фултон Хэл
- Официальный сайт сообщества Ruby
- Компактная шпаргалка по основам языка
- Подборка материалов по Ruby и Ruby On Rails
- Подборка интерактивных курсов по Ruby и Python