Ruby

Знакомство с языком Ruby

Проверка версии ruby

ruby -v

Обновление ruby

curl -L https://get.rvm.io | bash -s stable

Установка нужной версии ruby

rvm install ruby-2.4.2

Вывод сообщений в консоль

print - выводит строку без переносов (можно в конце указать \n) puts - выводит строку и ставит перенос на следующую строку

print "Привет, мир!\n"
print "Привет, мир!\n"
puts "Привет, мир!"
puts "Привет, мир!"

Переменные и типы данных

В ruby присутствует 5 типов данных:

  • int
  • float
  • string
  • boolean
  • nil
age = 29
puts(age) # 29
 
money = 29.80
puts(money) # 29.80
 
name = 'Олег'
isValid = true
none = nil # это отсутствие значения

 Строки и математические действия

  • downcase - приводит в нижний регистр
  • upcase - приводит в верхний регистр
  • strip - убирает пробелы
  • length - выводит длину
  • include? - позволяет проверить, включает ли переменная данное значение
words = 'Это очень '
word = '\'Мило\''
puts(words.downcase() + word.upcase())
 
nothing = '    Ничего    '
puts(nothing.strip())
 
length = 'Длина'
puts(length.length())
 
name = 'Валера'
puts(name.include? 'Ва')

У нас есть все основные операции, которые есть и в других языках.

Стоит отметить, что в puts мы складываем сейчас два разных типа данных, поэтому второй аргумент мы приводим к строке через to_s

x = 5
y = 11
 
res = x + y
res = x - y
res = x * y
res = x / y
res = x ** y
res = y % x
 
puts("Результат остатка от деления: " + res.to_s)
 
number = 14.55
 
puts(number.abs()) # выведет то же число
puts(number.round()) # округлит в большую сторону
puts(Math.sqrt(144)) # вычислит квадратный корень из 144

Получение данных от пользователя

С помощью функции gets мы можем в консоли получить текст от пользователя

puts('Hello, what\'s your name:');
name = gets;
puts("Asking for you," + name + ", man");
 
puts('Hello, what\'s your name:');
name = gets.chomp(); # отменит перевод на новую строку
puts("Asking for you," + name + ", man")

И тут мы сразу получаем значения и переводим их в числа через to_i или to_f

print("Первое число: ");
x = gets.chomp();
print("Второе число: ");
y = gets.chomp().to_i; # если нам нужны дробные числа, то переводим через to_f
puts(x.to_i + y);

Массивы и ассоциативные массивы

Массивы создаются через ключевое слово Array.

Ассоциативные массивы создаются внутри {} и пары ключ-значение заносятся через =>

arr = Array[1, 2, 3, 4, true, "Oleg"];
arrNames = Array['Oleg', 'Anton', 'Vladislav'];
 
puts(arr); # выведет весь массив
puts(arrNames[0]); # выведет один элемент
puts(arrNames[1, 2]); # выведет диапазон
 
list = Array.new; # создаём пустой массив без элементов
list[0] = 1;
list[4] = 4;
puts list.length(); # длина массива
puts list.reverse(); # выведет массив в обратном порядке
puts list.include? 1; # будет искать элемент в массиве
 
#ассоциативный массив
countries = {
    "RU" => "Russia",
    1 => "Australia",
    :US => "United States"
};
 
puts countries["RU"]; # выводим ассоциативное значение
puts countries[1];
puts countries[:US];

Методы и оператор return

Методы объявляются через оператор def

def sum(a, b)
  res = a + b
  return res
end
 
res = sum(3, 4)
puts res # Выведет 7

Условные операторы

Оператор if используется для выполнения блока кода, если заданное условие истинно

x = 5
if x > 10
  puts "x больше 10"
elsif x > 5
  puts "x больше 5"
else
  puts "x меньше или равно 5"
end

Оператор unless используется для выполнения блока кода, если заданное условие ложно

x = 5
unless x > 10
  puts "x меньше или равно 10"
else
  puts "x больше 10"
end

Цикл While и цикл For

Цикл while выполняет блок кода, пока заданное условие истинно

x = 0
while x < 5
  puts x
  x += 1
end

Цикл for используется для выполнения блока кода для каждого элемента в заданном наборе

for i in 1..5
  puts i
end

В Ruby цикл for часто заменяется циклом each

(1..5).each do |i|
  puts i
end

Работа с файлами (чтение и запись)

Для чтения содержимого файла в Ruby используется класс File

Пример построчного вывода строк из файла:

В этом примере, мы открываем файл с именем “file.txt” в режиме чтения ("r") и используем метод each_line, чтобы прочитать файл построчно. Затем мы выводим каждую строку на экран.

File.open("file.txt", "r") do |file|
  file.each_line do |line|
    puts line
  end
end

Для записи данных в файл также используется класс File. Вот пример, как записать строки в файл:

В этом примере мы открываем файл с именем “file.txt” в режиме записи ("w") и используем метод puts для записи строк в файл

File.open("file.txt", "w") do |file|
  file.puts "Hello, World!"
  file.puts "This is a sample file."
end

Когда мы работаем с файлом, важно закрыть его после окончания операций чтения или записи. Однако, в примерах выше использован блок do..end, который позволяет автоматически закрыть файл после выполнения кода в блоке. Это удобно и гарантирует правильное закрытие файла.

Также можно использовать методы File.read и File.write для чтения и записи файлов соответственно.

# Чтение файла целиком
content = File.read("file.txt")
puts content
 
# Запись в файл
File.write("file.txt", "Some content to write")

Отслеживание ошибок

В Ruby можно сгенерировать исключение с помощью ключевого слова raise. Оно может принимать опциональный параметр — класс исключения или объект исключения.

raise "Произошла ошибка"

Для обработки исключений в Ruby используется конструкция begin..rescue..ensure:

begin
  # Код, который может вызвать исключение
rescue Исключение_1
  # Действия при возникновении Исключение_1
rescue Исключение_2
  # Действия при возникновении Исключение_2
else
  # Действия при отсутствии исключений
ensure
  # Дополнительный код, который выполнится в любом случае
end

В блоке begin содержится код, который может вызвать исключение. Если исключение возникает, выполнение программы переходит в блок rescue с соответствующим типом исключения. Если исключений не возникает, выполняется блок else. Блок ensure выполняется всегда, независимо от наличия исключений

В этом примере, деление на ноль вызовет исключение ZeroDivisionError, которое будет перехвачено блоком rescue, и будет выведено сообщение “Поймано исключение: деление на ноль”.

begin
  x = 10 / 0 # Деление на ноль
rescue ZeroDivisionError
  puts "Поймано исключение: деление на ноль"
end

Если нужно перехватить все исключения, вы можете использовать блок rescue без указания конкретного типа исключения

begin
  # Код, который может вызвать исключение
rescue
  # Действия при возникновении любого исключения
end

Объекты и классы (ООП)

Классы объявляются с помощью ключевого слова class. Конструктор вызывается с помощью initialize. Чтобы инициализировать новый инстанс класса, нужно записать Имя_класса.new(значения для конструктора)

Применение символа @ перед именем переменной в Ruby позволяет ей стать экземплярной переменной, которая будет доступна в пределах текущего объекта класса

С помощью attr_accessor мы указываем те поля, которые будут присутствовать в классе (так же можно их не указывать, если мы сразу будем их инициализировать в конструкторе)

class Person
    attr_accessor :name, :age
  
    def initialize(name, age)
      @name = name
      @age = age
    end
  
    def say_hello
      puts "Привет, меня зовут #{@name} и мне #{@age} лет."
    end
  end
  
person = Person.new("Алиса", 25)
person.say_hello

Наследование, модули

Класс может наследовать свойства и методы от другого класса, который называется «родительским» или «суперклассом», используя ключевое слово class и оператор <

class Animal
  def speak
    puts "I can speak!"
  end
end
 
class Dog < Animal
  def bark
    puts "Woof!"
  end
end
 
dog = Dog.new
dog.speak   # I can speak!
dog.bark    # Woof!

Импорты

Первый файл с классом

file1.rb

class ClassA
  def method_a
    puts "Hello from ClassA"
  end
end

И далее, во втором файле, мы используем require_relative которым и импортируем файл целиком, чтобы использовать его внутри целевого модуля

file2.rb

require_relative 'file1'
 
class ClassB
  def initialize
    @instance_of_a = ClassA.new
  end
 
  def method_b
    @instance_of_a.method_a
  end
end
 
instance_of_b = ClassB.new
instance_of_b.method_b

Ruby on Rails

Основы, установка, структура проекта

Первым шагом вам нужно установить Ruby на свой компьютер. Можно скачать установщик Ruby с официального сайта ruby-lang.org.

Далее нужно установить Rails Rails:

gem install rails`

Далее нужно создать новое приложение

rails new myapp

И запустить сервер

rails server

Рельсы работают по самому обычному принципу для бэкэнд-приложений:

  • веб-сервер получает запрос от пользователя
  • далее этот запрос попадает в роутер, который определяет, в какой контроллер должен попасть запрос
  • контроллер связан с Model тех данных, с которыми будут происходить операции и с View, который отвечает за связывание моделей с их отображением и уходом к конечному пользователю

При первом создании приложения, у нас генерируется огромная структура:

  • app - хранит весь код приложения
  • bin - хранит все исполняемые файлы
  • config - хранит routes.rb, который хранит те настройки, какой роут каким контроллером обрабатывать + там находятся конфиги
  • db - тут хранятся миграции баз данных
  • lib - хранятся руби-файлы
  • log - логи сервера
  • public - лежит то, что публично будет отдаваться с сервера
  • storage - туда будут загружаться файлы пользователей
  • test - тесты приложений
  • tmp - тут хранятся временные файлы
  • vendor - тут хранятся файлы внешние библиотеки не из руби
  • Rakefile - файл с кастомными задачами, которые можно запускать в проекте
  • config.ru - файл, который описывает, как запускать приложение

Вот пример того, что отдаёт сервер на фронт

Совет:

Файл .ruby-verison следует удалить и версию руби внутри Gemfile тоже стоит удалить, чтобы не было проблем у пакетов с разными версиями руби

Модели, миграции, ORM, CRUD

Каждая модель у нас отвечает за таблицу в базе данных

Для генерации модели

rails generate model User name:string registration_date:date
rails generate model Category key:string:name description:text
rails generate model Post title:string body:text category:references image:string
rails generate model Comment rating:integer body:text created_at:date post:references

После создания каждой модели, у нас в db/migrate создаются миграции, которые пойдут на сервер

class CreateCategories < ActiveRecord::Migration[7.0]
  def change
    create_table :categories do |t|
      t.string :key
      t.string :name
      t.text :description
 
      t.timestamps
    end
  end
end

Далее очень важной частью являются миграции. Миграции описывают структуру изменений в БД.