ЗмістНатисність на посилання, щоб перейти до потрібного місця
У Ruby існує кілька способів порівняння. Вони схожі на перший погляд, але працюють зовсім по-різному.
== (перевірка рівності значень)
- Перевіряє, чи мають об’єкти однаковий зміст.
- Часто перевизначається у класах (String, Array, Hash), щоб порівнювати значення, а не ідентичність.
a = "hello" b = "hello" a == b # => true a.equal?(b) # => false
== питає: "Чи однаковий зміст у цих об’єктів?"
equal? (перевірка ідентичності об’єктів)
- Перевіряє, чи це один і той самий об’єкт у пам’яті.
- Не перевизначається у класах, завжди порівнює об’єктні id.
a = "hello" b = "hello" c = a a.equal?(b) # => false a.equal?(c) # => true
Тут для розуміння всього цього діла, треба знати що таке об'єкт в Ruby.
eql? (сувора перевірка рівності для хешів та чисел)
- Перевіряє значення і тип.
- В основному використовується в хешах для ключів.
1 == 1.0 # => true 1.eql?(1.0) # => false, бо різні класи (Integer vs Float)
eql? більш суворий, ніж ==.
=== (case-match оператор)
- Використовується переважно у конструкції case (розберемо це нижче).
- Для різних класів поводиться по-різному:
- У класів (String, Integer) - перевіряє, чи об’єкт належить до класу (is_a?).
- У регулярних виразах - перевіряє, чи рядок підпадає під паттерн.
- У Range - чи входить об’єкт у діапазон.
case 5 when 1..10 "В діапазоні" # => "В діапазоні" end String === "hello" # => true /ell/ === "hello" # => true
Розглянемо трохи детальніше приклад з case. Як працює case … when у Ruby?
Синтаксис:
case об’єкт when зразок1 код1 when зразок2 код2 else код_за_замовчуванням end
Що відбувається під капотом
Ruby робить приблизно так:
if зразок1 === об’єкт код1 elsif зразок2 === об’єкт код2 else код_за_замовчуванням end
Тобто when автоматично використовує === для порівняння з case-значенням.
Далі приклади для різних типів
Діапазон (Range)
case 5 when 1..10 "В діапазоні" else "Поза діапазоном" end # => "В діапазоні"
Працює так, ніби Ruby виконує (це псевдо код):
(1..10) === 5 # => true
Але важливо зазначити, що звичайне використання === на числах чи інших типах не обов’язково працює так само:
10 === (1..20) # => false 10 == (1..20) # => false (1..20) == 10 # => false
Тут Range#=== перевіряє, чи входить число у діапазон.
Клас
case "hello" when String "Це рядок" when Integer "Це число" end # => "Це рядок"
Ruby виконує:
String === "hello" # => true Integer === "hello" # => false
Для класів === — це скорочення для obj.is_a?(Клас).
c) Регулярний вираз
case "hello" when /ell/ "Збіг з паттерном" else "Немає збігу" end # => "Збіг з паттерном"
Під капотом:
/ell/ === "hello" # => true
Для Regexp === перевіряє, чи рядок відповідає паттерну.
Ми відійшли трохи від теми === і перейшли до case (бо там === під капотом). Такий простий оператор, але робить різні штуки.
Щоб простіше запам'ятати:
- case x; when y - це не x == y, а y === x.
- === працює по-різному залежно від типу y:
- Class -> is_a?
- Range -> include?
- Regexp -> =~ (збіг рядка)
Це дозволяє дуже гнучко писати умови.
Цей допис поки що не має жодних доповнень від автора/ки.