Ruby: Всё есть объект
Ruby по своим возможностям и подходам в разработке близок к JavaScript и Python, но имеет свои особенности. Разработчики языка во многом опирались на Smalltalk, Lisp (это семейство языков), Perl и другие подобные языки. Это привело к интересному результату. Во-первых, Ruby — очень объектно-ориентированный язык. В Ruby всё есть объект, включая nil
(это аналог null
), и каждая операция — это вызов метода:
'hexlet'.reverse # telxeh
1.7.round # 2
nil.to_i # 0
1 + 1 # на самом деле 1.+(1)
Одна из сильных сторон Ruby – стандартная библиотека. Она решает практически все возникающие задачи. В одних только строках 185 встроенных методов!
Это одна из причин, почему Ruby чаще других выигрывает в CodeBattle
# Количество методов у разных типов данных
# В примерах ниже вызывается метод methods,
# хотя кажется, что это обращение к свойству
''.methods.count # 185
1.methods.count # 145
[].methods.count # 191
В Ruby всё, кроме присваивания, это вызовы методов. Такой подход позволяет переопределять буквально любое поведение:
# То, что на самом деле происходит, когда мы выполняем «операции»
1.+(5) # 6
1.>(3) # false
На этом основано очень много кода, особенно библиотечного. Например, у любого объекта можно определить синтаксис, аналогичный доступу к массиву []
. Или можно определить операции для дат, сделав работу с ними максимально простой (как в примере прошлого урока). А вот как выглядят сеттеры у объектов:
# Кажется, что это прямое изменение свойства
# На самом деле это сеттер object.key=('value')
obj.key = 'value'
Все данные в Ruby — это объекты. Например nil
, представлен классом NilClass
, и является единственным его объектом. true
— объект класса TrueClass
, а false
— объект класса FalseClass
. У остальных типов свои классы.
Узнать класс любого объекта можно так:
1.class # Integer
''.class # String
nil.class # NilClass
С другой стороны классы в Ruby — тоже объекты, у которых есть свои классы 0_o. Но это уже совсем другая история) Есть даже такая шутка (но это не шутка): в Ruby объект это класс, а класс — это объект. Почему это так – узнаем чуть позже.
Отладочная печать
Иногда в работе приходится прибегать к отладочной печати и в Ruby есть несколько особенностей, о которых надо знать. Функция puts()
выводит любые типы данных без необходимости преобразования их в строку. С другой стороны, такой вывод не останавливает выполнение и иногда это неудобно, если хочется посмотреть только первый вывод. Для таких ситуаций лучше использовать выброс исключения, которое и выведет на экран нужную информацию и прервёт выполнение. Делается это так:
# raise – бросить исключение
# .inspect – метод, который преобразует
# любые данные в строковое представление
raise something.inspect
Задание
Напечатайте на экран следующий вызов:
# Здесь выводятся на экран все методы строк,
# которые содержат знак вопроса в имени
# Фактически — это вывод списка предикатов
# То же самое можно сделать для любого типа
puts 'hexlet'.methods.grep(/\?/)
# Будет выведено около 20 имен
Упражнение не проходит проверку — что делать? 😶
Если вы зашли в тупик, то самое время задать вопрос в «Обсуждениях». Как правильно задать вопрос:
- Обязательно приложите вывод тестов, без него практически невозможно понять что не так, даже если вы покажете свой код. Программисты плохо исполняют код в голове, но по полученной ошибке почти всегда понятно, куда смотреть.
В моей среде код работает, а здесь нет 🤨
Тесты устроены таким образом, что они проверяют решение разными способами и на разных данных. Часто решение работает с одними входными данными, но не работает с другими. Чтобы разобраться с этим моментом, изучите вкладку «Тесты» и внимательно посмотрите на вывод ошибок, в котором есть подсказки.
Мой код отличается от решения учителя 🤔
Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи.
В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.
Прочитал урок — ничего не понятно 🙄
Создавать обучающие материалы, понятные для всех без исключения, довольно сложно. Мы очень стараемся, но всегда есть что улучшать. Если вы встретили материал, который вам непонятен, опишите проблему в «Обсуждениях». Идеально, если вы сформулируете непонятные моменты в виде вопросов. Обычно нам нужно несколько дней для внесения правок.
Кстати, вы тоже можете участвовать в улучшении курсов: внизу есть ссылка на исходный код уроков, который можно править прямо из браузера.