Użyję Pythona jako przykładu tego, czego szukam (możesz myśleć o tym jak o pseudokodzie, jeśli nie znasz Pythona):
>>> a = 1
>>> type(a)
<type 'int'>
Wiem, że w rubinie mogę:
1.9.3p194 :002 > 1.class
=> Fixnum
Ale czy jest to właściwy sposób na określenie rodzaju obiektu?
isinstance
lub sprawdzać odpowiedzi. Ale po prostu mówiąc „NIE !!!” nie jest naprawdę pomocny, prawda? Zamiast tego rozważ edukację.Odpowiedzi:
Właściwym sposobem określenia „typu” obiektu, który jest niestabilnym terminem w świecie Ruby, jest wywołanie
object.class
.Ponieważ klasy mogą dziedziczyć po innych klasach, jeśli chcesz ustalić, czy obiekt jest „określonego typu”, możesz wywołać,
object.is_a?(ClassName)
aby sprawdzić, czyobject
jest on typu,ClassName
czy pochodzi z niego.Zwykle sprawdzanie typów nie jest wykonywane w Rubim, ale obiekty są oceniane na podstawie ich zdolności do reagowania na określone metody, zwane potocznie „ Typowaniem kaczym ”. Innymi słowy, jeśli odpowiada on wybranym metodom, nie ma powodu, aby zwracać szczególną uwagę na ten typ.
Na przykład
object.is_a?(String)
jest zbyt sztywny, ponieważ inna klasa może zaimplementować metody, które przekonwertują go na ciąg znaków lub sprawią, że będzie on zachowywał się identycznie jak łańcuch.object.respond_to?(:to_s)
byłby lepszym sposobem sprawdzenia, czy dany obiekt robi to, co chcesz.źródło
#class
nie nie zwraca typ obiektu, zwraca swoją klasę . Nazwa powinna być martwym prezentem. Klasa i typ to dwie zupełnie różne koncepcje w OO.typeof
od C, JavaScript i innych jestclass
. W Rubim nie ma formalnego systemu protokołów, tak jak w innych językach, a Objective-C jest najbliższym spokrewnionym z nim językiem. Jeśli definiujesz „typ” jako „obiekt, który reaguje na określony zestaw metod z akceptowalnymi wynikami”, to tak naprawdę nie ma sposobu, aby to potwierdzić. Jest po prostu zbyt luźny. Przez większość czasu w Rubim, gdy mowa jest o typie obiektu, zrozumiałe jest, że mówisz o klasie. Właśnie z tego powodu użyłem tego typu w cudzysłowie.int i
” lub „Integer j
”). Tadman odpowiedział na pytanie w sposób, który zdawał się spełniać zarówno pytającego oraz publiczność, wyjaśniając jednocześnie terminologię, której używa Ruby. Nie interesuje mnie rozwiązywanie kwestii akademickich na temat drobniejszych aspektów terminologii zorientowanej obiektowo, więc proszę o ostatnie słowo.możesz także spróbować:
instance_of?
źródło
Często w Ruby nie obchodzi cię, czym jest klasa obiektu, po prostu zależy ci, żeby zareagował na określoną metodę. Jest to znane jako Pisanie kaczek i zobaczysz je we wszystkich bazach kodu Ruby.
Tak więc w wielu (jeśli nie w większości) przypadkach najlepiej jest używać Duck Typing, używając
#respond_to?(method)
:źródło
Powiedziałbym tak". Jak powiedział „Matz” w jednym ze swoich wystąpień: „Obiekty Ruby nie mają typów”. Nie wszystko, ale część, którą próbuje nam przekazać. Dlaczego więc ktoś powiedziałby „wszystko jest przedmiotem”? Aby dodać, powiedział: „Dane mają typy, a nie obiekty”.
Więc możemy się tym cieszyć.
https://www.youtube.com/watch?v=1l3U1X3z0CE
Ale Ruby nie przejmuje się zbytnio typem obiektu, tylko klasą. Używamy klas, a nie typów. Wszystkie dane mają wtedy klasę.
Mogą mieć także przodków
Mają też meta-klasy, ale oszczędzę ci szczegółów na ten temat.
Gdy poznasz klasę, będziesz w stanie sprawdzić, jakich metod możesz użyć. Właśnie tam potrzebny jest „typ danych”. Jeśli naprawdę chcesz poznać szczegóły, sprawdź ...
„Rubinowy model obiektowy”
Jest to termin używany do tego, jak Ruby obsługuje obiekty. Wszystko jest wewnętrzne, więc tak naprawdę nie widać zbyt wiele, ale dobrze jest wiedzieć. Ale to inny temat.
Tak! Klasa jest typem danych. Obiekty mają klasy, a dane mają typy. Jeśli więc wiesz o bazach danych, to wiesz, że istnieje tylko skończony zestaw typów.
liczby bloków tekstu
źródło
Object.ancestors # => [Object, Kernel, BasicObject]