Я провел некоторое время, играя с irb, и придумал следующее:
class BasicObject
def class
klass = class << self; self; end # get the object's singleton class
klass.superclass # the superclass of an object's singleton class is that object's class
end
end
Это даст любому объекту, унаследованному от BasicObject, #class
метод, который вы можете вызвать.
Редактировать
Дополнительные пояснения в соответствии с просьбой в комментариях:
Скажем, у вас есть объект obj
, который является экземпляром класса Foo
. obj
получает методы своего экземпляра от тех, которые определены в классе Foo
, в дополнение к методам, определенным в родительском классе Foo
, и так далее в цепочке наследования. Ruby позволяет вам определять методы непосредственно для объекта, которые доступны только этому конкретному объекту, как этот
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
Причина, по которой вы можете это сделать, заключается в том, что у каждого объекта есть нечто, называемое одноэлементным классом (или иногда называемым собственным классом), для которого вы фактически определяете метод. Этот одноэлементный класс фактически существует в цепочке наследования объекта непосредственно под фактическим классом объекта. Это делает фактический класс объекта, Foo
в этом примере, суперклассом синглтон-класса объекта.
Строка class << self
, которую вы видите в ответе, является специальным синтаксисом для ввода области видимости одноэлементного класса объекта. Таким образом, в приведенном выше примере вы также можете определить метод в одноэлементном классе объекта, например:
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
Таким образом, строка class << self; self; end
открывает одноэлементный класс объекта (независимо от того, какой объект в настоящее время self
) и затем возвращает self
(self
теперь стал одноэлементным классом), который затем может быть назначен переменной делать то, что вы хотите с
Я бы порекомендовал прочитать Metaprogramming Ruby , если вы хотите получить лучшее объяснение всего этого. Это определенно дает вам лучшее понимание объектной модели Ruby в целом.