Когда я только начинал изучать Ruby, я посоветовал своему другу прочитать пару книг, чтобы выучить язык. Мы просто пролистывали книгу, потому что думали, что уже хорошо владеем языком, поскольку создали наше гениальное приложение для продажи продуктов, которое также продает канцелярские товары. Но самый первый абзац потряс нас до core - это заставило нас понять, как и все начинающие разработчики, у нас был момент необоснованной уверенности.

Все, чем вы манипулируете, является объектом, а результаты этих манипуляций сами являются объектами.

Да хоть строчки и цифры! Что ж, в этом есть смысл, как еще у строки был бы метод object_id? Все, чем вы управляете, является объектом, даже если это целое число, строка, массив и т. Д. Итак, если все является объектом, а объект является экземпляром класса, тогда должен существовать класс, определенный с помощью методов. Поскольку object_id существует как в целочисленном, так и в строковом классе, мы думали, что будет родительский класс. Мы можем найти это с помощью метода ancestors:

1.object_id
=> 3
1.class
=> Integer
1.class.ancestors
=> [Integer, Numeric, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
"Foo".class.ancestors
=> [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]

Почти все классы Ruby автоматически наследуются от класса Object, что объясняет, как у нас есть метод object_id почти во всем. Все объекты Ruby созданы с определенными врожденными способностями, которые они умеют выполнять, потому что они являются объектами Ruby.

Самые первые несколько строк в книге дали нам обоим такое глубокое понимание. Мы поняли, что все является объектом, и мы отправляем сообщения объекту / вызываем метод объекта. Мы с радостью вернулись к нашему обычному просмотру текстов на Ruby.

Тогда мой друг остановил меня и спросил: «Так как же работают математические операторы?» на что я ответил: «Что значит« как? »»

«Хорошо, если все является объектом, и если мы вызываем методы для объекта, как a + b работает?» Что ж, это меня удивило, я никогда об этом не думал. Самое первое, что я сделал, чтобы узнать об этом больше, - это проверить методы, доступные для целых чисел, вызвав methods в экземпляре Integer.

2.methods # Returns an array of public and protected methods

methods вернул огромный массив общедоступных и защищенных методов, включая метод+, который помог нам понять, a + b - это магия парсера, которая примерно преобразует его в a.+ b

1 + 2
=> 3
1.+(2)
=> 3

Итак, чтобы доказать, что под капотом a + b вызывает a.+(b), я решил открыть класс Integer и изменить метод +, чтобы он возвращал вычитаемое значение вместо добавленного.

  • Этот код по какой-то причине не работает в irb, но отлично работает в pry.
class Integer
  def +(num)
    self - num   # self is the integer on which + method is called
  end
end
=> :+
2 + 3
=> -1

Короче говоря, «все, что вы обрабатываете в Ruby, является либо объектом, либо конструкцией, которая оценивается как объект, и каждый объект является экземпляром некоторого класса». Capiche?