Вдохновленный этим обсуждением, после некоторого поиска с помощью Google я не смог найти ответ на довольно простой вопрос относительно методов в Ruby: объекты методов или нет?
Тут и там существуют различные мнения, и я действительно хотел бы услышать, скажем, всестороннее объяснение.
Я знаю Object#method
метод, который берет имя метода и возвращает a Method
экземпляр, но, с другой стороны, существует подобная вещь, которую можно сделать с блоками для создания их в Proc
экземпляры и блоки не являются объектами, поэтому что делает методы несколько отличающимися?
Методы являются фундаментальной частью синтаксиса Ruby, но они не являются значениями , с которыми могут работать программы Ruby. { {1}} То есть методы Ruby не являются объектами в отличие от строк, чисел и массивов. Однако возможно получить объект Method , который представляет данный метод, , и мы можем вызывать методы косвенно через объекты Method.
В Ruby методы и блоки сами по себе не являются собственными или первоклассными объектами. Однако их очень легко можно обернуть предметами, так что, как правило, это не имеет значения.
Но попробуйте и запомните результат
a = Object.method(:new).object_id
b = Object.method(:new).object_id
a == b
=> false
В Haskell все значения (включая числа, а также лямбды и функции) являются первоклассными значениями. Во всех аспектах языка все они трактуются одинаково. В Ruby это не так, но это можно приблизить.
Сложно сказать.
Единственный способ получить доступ к методу - отправить сообщение #method
какому-либо объекту, который затем вернет объект Method
. Но является ли этот объект Method
самим методом? Или это обертка вокруг метода? Или это преобразованная версия исходного метода?
Вы не можете знать: если вы хотите просмотреть метод, вы должны вызвать #method
, после чего вы определенно получит объект. Что это было до , которое вы назвали #method
, вы не можете посмотреть, поэтому вы не можете сказать.
Пара точек данных: в Ruby все возвращает значение. Что возвращает def
? Он всегда возвращает nil
, а не объект Method
. А define_method
? Он возвращает Proc
, но не Method
(ни UnboundMethod
). [Примечание: в Rubinius def
возвращает скомпилированный байт-код метода, но не объект Method
.]
Если вы посмотрите на 4-й и 5-й абзацы Раздела 6.1 спецификации языка Ruby (строки 29-34 и 1-5 на страницах 5 и 6), вы можете ясно видеть, что существует различие между методами и объектами. И если вы посмотрите на спецификацию встроенных классов, вы обнаружите, что там нет ни Method
, ни UnboundMethod
, ни Object # method
.IOW: вы можете создать полностью совместимый со стандартами интерпретатор Ruby, в котором методы не являются объектами.
Теперь блоки OTOH определенно не являются объектами. Есть много способов построить объекты Proc
из блоков, которые затем будут иметь то же поведение, что и исходный блок ( лямбда
, proc
, Proc.new
, сигил &
), но сами блоки не являются объектами.
Подумайте об этом так: вы можете передать строку в File.new
для создания файлового объекта, но это не сделает строку файлом. Вы можете передать блок в Proc.new
для создания объекта процедуры, но это не делает блок процедурой.