Как Ruby полностью объектно ориентирован?

Итак, мне любопытно, как Ruby - полностью объектно-ориентированный язык. Я наткнулся на одну проблему, которая мне не совсем понятна.

Если я определяю функцию следующим образом

def foo(text)
  print text
end

и я определяю функцию вне класса, как эта функция является объектом? Я понимаю, что я могу позвонить

foo.class

И я получаю NilClass. Означает ли это, что foo является экземпляром NilClass? И если это так, что это значит, когда я называю

foo "hello world"

Если foo является объектом, какой метод я вызываю, когда я делаю выражение, как указано выше. Кроме того, если это объект, означает ли это, что я могу изменить его и добавить к нему другой метод (скажем, бар), где я мог бы сделать следующий статус:

foo.bar(some variables)

Извините, я немного немного смущен в этом вопросе. Любое разъяснение очень ценится! Спасибо!

Ответ 1

  • Пользовательские глобальные функции (функции верхнего уровня) - это методы экземпляра Object (хотя класс self не Object).
  • Методы верхнего уровня всегда являются частными.

Ответ 2

Как состояния Википедии:

Все методы, определенные вне области действия конкретного объекта, на самом деле являются методами класса Object.

Ruby на самом деле "мультипарадигма". Он поддерживает объектно-ориентированные, функциональные, императивные (и некоторые другие) парадигмы.

Быть "полностью объектно-ориентированным" не означает, что вы поддерживаете только объектно-ориентированную парадигму. Пока вы поддерживаете все функции, которые составляют объектно-ориентированное программирование (классы, экземпляры, полиморфизм и т.д.), Вы все равно можете поддерживать дополнительные парадигмы и по-прежнему быть "полностью объектно-ориентированными".

Ответ 3

foo.class сначала вызывает метод foo, который возвращает nil, а затем вызывает метод class объекта, возвращенного из foo, а именно nil.

В псевдокодной нотации, оценивая код шаг за шагом:

foo.class
==> { print text }.class
==> { nil }.class
==> nil.class
==> NilClass

Ответ 4

Вы можете получить метод как объект. Чтобы использовать ваш пример:

def foo(text)
  print text
end

а затем разверните его:

method_as_object = method(:foo)
method_as_object.call('bar') #=> bar

Обычно, когда вы определяете метод, вы просто определяете его как метод текущей области (по умолчанию это класс Object)

Ответ 5

Чтобы расширить пример Justice, вы можете это сделать еще дальше.

def foo
    puts "foo"
end

foo.class
==> NilClass
NilClass.class
==> Class
Class.superclass
==> Module
Module.superclass
==> Object
Object.superclass
==> BasicObject

Все это экземпляр класса BasicObject, по крайней мере.