Методы в Ruby: объекты или нет?

Вдохновленный этим обсуждением, после некоторого поиска с помощью Google я не смог найти ответ на довольно простой вопрос относительно методов в Ruby: объекты методов или нет?

Тут и там существуют различные мнения, и я действительно хотел бы услышать, скажем, всестороннее объяснение.

Я знаю Object#method метод, который берет имя метода и возвращает a Method экземпляр, но, с другой стороны, существует подобная вещь, которую можно сделать с блоками для создания их в Proc экземпляры и блоки не являются объектами, поэтому что делает методы несколько отличающимися?

43
задан Community 23 May 2017 в 11:54
поделиться

3 ответа

Методы являются фундаментальной частью синтаксиса Ruby, но они не являются значениями , с которыми могут работать программы Ruby. { {1}} То есть методы Ruby не являются объектами в отличие от строк, чисел и массивов. Однако возможно получить объект Method , который представляет данный метод, , и мы можем вызывать методы косвенно через объекты Method.

Из Язык программирования Ruby :
alt text

61
ответ дан 26 November 2019 в 22:46
поделиться

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

Но попробуйте и запомните результат

a = Object.method(:new).object_id
b = Object.method(:new).object_id
a == b
=> false

В Haskell все значения (включая числа, а также лямбды и функции) являются первоклассными значениями. Во всех аспектах языка все они трактуются одинаково. В Ruby это не так, но это можно приблизить.

11
ответ дан 26 November 2019 в 22:46
поделиться

Сложно сказать.

Единственный способ получить доступ к методу - отправить сообщение #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 для создания объекта процедуры, но это не делает блок процедурой.

18
ответ дан 26 November 2019 в 22:46
поделиться
Другие вопросы по тегам:

Похожие вопросы: