Spędziłem trochę czasu gry z IRB i podszedł z tym:
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
To da dowolny obiekt, który dziedziczy BasicObject się #class
metody, które można nazwać.
Edit
Dalsze wyjaśnienia na żądanie w komentarzach:
Powiedzmy, że masz obiekt obj
który jest instancją klasy Foo
. obj
pobiera metody instancji od tych, które są zdefiniowane w klasie Foo
, oprócz metod zdefiniowanych w klasie nadrzędnej Foo
i tak dalej w łańcuchu dziedziczenia. Ruby pozwala definiować metody bezpośrednio na obiekcie, które są dostępne tylko dla tego konkretnego obiektu jak ten
obj = Foo.new
def obj.hello
puts "hello"
end
obj.hello #=> hello
other_obj = Foo.new
other_obj.hello #=> Method missing error
Powodem można to zrobić, ponieważ każdy przedmiot ma coś, co nazywa klasą Singleton (lub czasami nazywamy eigenclass), które faktycznie określasz metodę na. Ta klasa singletona faktycznie istnieje w łańcuchu dziedziczenia obiektu bezpośrednio pod rzeczywistą klasą obiektu. To czyni klasę rzeczywistą obiektu, Foo
w tym przykładzie, nadklasą klasy singleton obiektu.
Wiersz class << self
, który widzisz w odpowiedzi, to specjalna składnia do wprowadzania zakresu pojedynczej klasy obiektu. Tak więc w powyższym przykładzie, można również zdefiniować metodę w Singleton klasy obiekt wygląda tak
class << obj
def goodbye
puts "goodbye"
end
end
obj.goodbye #=> goodbye
więc linia class << self; self; end
otwiera klasę singleton obiektu (cokolwiek obiekt jest obecnie self
), a następnie powrocie self
(self
ma teraz stają się klasą singleton), które można następnie przypisać do zmiennej, aby robić to, co chcesz.
Polecam lekturę Metaprogramming Ruby, jeśli chcesz uzyskać lepsze wyjaśnienie tego wszystkiego. To zdecydowanie daje dużo lepsze zrozumienie modelu obiektu Ruby jako całości.
można dać nieco bardziej konkretny przykład tego, co próbujesz zrobić? Pytasz "Jeśli mam klasę Foo, która dziedziczy po BasicObject, czy istnieje sposób na określenie, że instancją tej klasy jest" Foo "w przeciwieństwie do BasicObject"? Nie jestem pewien, o co pytasz. –
Właściwie, tak dokładnie! Zmiana postu w celu wyjaśnienia: – Jwosty
'MyObjectSystem.class.name'? –