294 lines
7.1 KiB
Markdown
294 lines
7.1 KiB
Markdown
---
|
|
status: processing
|
|
type: knowledge
|
|
tags:
|
|
- programming
|
|
- ruby
|
|
created: 2026-05-17
|
|
updated: 2026-05-26
|
|
source:
|
|
- '[[90 Library/Programming/Ruby/Ruby - основы языка]]'
|
|
- '[[Знания Ruby]]'
|
|
aliases:
|
|
- Ruby - основы языка
|
|
---
|
|
# Ruby — основы языка
|
|
|
|
Ruby — объектно-ориентированный язык, но допускает процедурный стиль написания кода. Всё является объектом, включая числа и булевы значения.
|
|
|
|
Связанные темы: [[Ruby On Rails - MOC]]
|
|
|
|
## Синтаксис
|
|
|
|
- Знак препинания в конце строки не нужен
|
|
- Отступы не несут синтаксического смысла (в отличие от Python)
|
|
- Несколько команд в одной строке разделяются через `;`
|
|
|
|
```ruby
|
|
puts "Hello World!"
|
|
puts 42; puts "next line"
|
|
```
|
|
|
|
## Комментарии
|
|
|
|
```ruby
|
|
# однострочный комментарий
|
|
|
|
=begin
|
|
многострочный
|
|
комментарий
|
|
=end
|
|
```
|
|
|
|
## Типы данных
|
|
|
|
```ruby
|
|
"Hello".class # => String
|
|
true.class # => TrueClass
|
|
5.class # => Integer
|
|
6.4.class # => Float
|
|
nil.class # => NilClass
|
|
```
|
|
|
|
### Именование
|
|
|
|
- Переменные — с маленькой буквы: `my_var`
|
|
- Классы — с большой буквы: `MyClass`
|
|
- Ключевые слова языка использовать нельзя
|
|
|
|
### Преобразование типов
|
|
|
|
**Явное:**
|
|
|
|
| Метод | Что делает |
|
|
|--------|-----------------------------------------|
|
|
| `to_i` | к целому числу (дробная часть отсекается) |
|
|
| `to_f` | к вещественному числу |
|
|
| `to_s` | к строке |
|
|
|
|
**Неявное:** при математических операциях `Integer + Float` → `Float`.
|
|
|
|
## Значения по умолчанию
|
|
|
|
Для присваивания значения по умолчанию часто используют `||=`:
|
|
|
|
```ruby
|
|
a ||= 'что-то'
|
|
# то же самое, что:
|
|
a = a || 'что-то'
|
|
```
|
|
|
|
Это работает из-за того, что в Ruby только `nil` и `false` считаются falsey. Все остальные значения, включая `0`, пустую строку и пустой массив, в условиях считаются truthy.
|
|
|
|
Ограничение: `||=` не подходит, если `false` — допустимое сохранённое значение.
|
|
|
|
## Предикаты
|
|
|
|
В Ruby проверки часто оформляют методами-предикатами с `?` на конце:
|
|
|
|
```ruby
|
|
0.zero? # => true
|
|
1.zero? # => false
|
|
2.positive? # => true
|
|
|
|
8.even? # => true
|
|
8.odd? # => false
|
|
|
|
''.empty? # => true
|
|
'wow'.empty? # => false
|
|
|
|
something.nil?
|
|
items.any?
|
|
items.empty?
|
|
```
|
|
|
|
## Управляющие конструкции
|
|
|
|
```ruby
|
|
# if без ветвления
|
|
if a > 0
|
|
action
|
|
end
|
|
|
|
# if-elsif-else
|
|
if a > 0
|
|
...
|
|
elsif a == 0
|
|
...
|
|
else
|
|
...
|
|
end
|
|
|
|
# unless — выполнится, если условие ложно
|
|
unless a > 0
|
|
action
|
|
end
|
|
|
|
# case
|
|
case a
|
|
when 1 then puts "один"
|
|
when 2 then puts "два"
|
|
else puts "другое"
|
|
end
|
|
```
|
|
|
|
### Альтернативные условия
|
|
|
|
Тернарный оператор — короткая форма `if/else`, когда нужно выбрать одно из двух значений:
|
|
|
|
```ruby
|
|
condition ? value_if_true : value_if_false
|
|
```
|
|
|
|
Пример:
|
|
|
|
```ruby
|
|
age = 20
|
|
status = age >= 18 ? 'adult' : 'minor'
|
|
# => "adult"
|
|
```
|
|
|
|
Обычный `if/else` для того же случая:
|
|
|
|
```ruby
|
|
status =
|
|
if age >= 18
|
|
'adult'
|
|
else
|
|
'minor'
|
|
end
|
|
```
|
|
|
|
Тернарный оператор удобен, когда обе ветки короткие и возвращают простые значения:
|
|
|
|
```ruby
|
|
message = user.nil? ? 'Гость' : user.name
|
|
price = discount ? base_price * 0.9 : base_price
|
|
```
|
|
|
|
Если логика занимает несколько строк, лучше использовать обычный `if/else`. Вложенные тернарные операторы тоже лучше не писать: они быстро становятся нечитаемыми.
|
|
|
|
Плохой вариант:
|
|
|
|
```ruby
|
|
result = a > 0 ? 'positive' : a < 0 ? 'negative' : 'zero'
|
|
```
|
|
|
|
Постфиксный `if` используют для коротких выражений:
|
|
|
|
```ruby
|
|
do_something if num.zero?
|
|
```
|
|
|
|
`unless` выполняет блок, если условие ложно:
|
|
|
|
```ruby
|
|
unless something.zero?
|
|
do_something
|
|
end
|
|
```
|
|
|
|
Сложные условия внутри `unless` лучше не писать: `unless a && b` читается хуже явного `if`.
|
|
|
|
## Логические операторы
|
|
|
|
```ruby
|
|
true && false # => false
|
|
false || true # => true
|
|
!true # => false
|
|
```
|
|
|
|
Сравнение с логическими значениями строгое:
|
|
|
|
```ruby
|
|
true == 1 # => false
|
|
false == nil # => false
|
|
```
|
|
|
|
Логические операторы возвращают не обязательно `true` или `false`, а последнее вычисленное значение:
|
|
|
|
```ruby
|
|
0 && 'one' # => "one"
|
|
nil && false # => nil
|
|
```
|
|
|
|
## Оператор `<=>`
|
|
|
|
`<=>` называют spaceship-оператором. Он возвращает `-1`, `0` или `1` и часто используется при сортировке:
|
|
|
|
```ruby
|
|
1 <=> 1 # => 0
|
|
2 <=> 1 # => 1
|
|
1 <=> 2 # => -1
|
|
```
|
|
|
|
## Строки
|
|
|
|
Конкатенация:
|
|
|
|
```ruby
|
|
name = 'H' + 'e' + 'x' + 'l' + 'e' + 't'
|
|
name = 'H' 'e' 'x' 'l' 'e' 't'
|
|
```
|
|
|
|
Интерполяция работает только в двойных кавычках:
|
|
|
|
```ruby
|
|
greeting = "hello #{name}"
|
|
line_feed = "one line\nanother one"
|
|
```
|
|
|
|
Полезные методы:
|
|
|
|
```ruby
|
|
name = 'ruby'
|
|
name.upcase # => "RUBY"
|
|
name.include?('ru')
|
|
name.capitalize # => "Ruby"
|
|
name.length # => 4
|
|
```
|
|
|
|
Срезы:
|
|
|
|
```ruby
|
|
name = 'ruby'
|
|
name[1] # => "u"
|
|
name[-1] # => "y"
|
|
name[0, 2] # => "ru"
|
|
name[0..-2] # => "rub"
|
|
name[-4..] # => "ruby"
|
|
name[/ru/] # => "ru"
|
|
```
|
|
|
|
Пример маскирования номера карты:
|
|
|
|
```ruby
|
|
def prepare_card_for_display(num)
|
|
"**#{num[-4..]}"
|
|
end
|
|
```
|
|
|
|
## Циклы
|
|
|
|
| Оператор | Назначение |
|
|
|----------|-----------|
|
|
| `loop` | бесконечный цикл; выход через `break` |
|
|
| `while` | цикл с условием выполнения |
|
|
| `until` | цикл, пока условие ложно |
|
|
| `for` | итератор по перечислимому объекту |
|
|
| `next` | пропустить текущий шаг |
|
|
| `redo` | повторить текущий шаг заново |
|
|
|
|
**Диапазоны в `for`:**
|
|
|
|
```ruby
|
|
for i in 1..5 # от 1 до 5 включительно
|
|
for i in 1...5 # от 1 до 4 (5 не входит)
|
|
```
|
|
|
|
**Деление с остатком:**
|
|
|
|
```ruby
|
|
x, r = x.divmod(n)
|
|
```
|