2013-04-02 7 views
245

Я буду использовать Python в качестве примера того, что я ищу (вы можете думать об этом как псевдокоде, если вы не знаете, Python):Определение типа объекта в рубин

>>> a = 1 
>>> type(a) 
<type 'int'> 

I знаю в рубине Я могу сделать:

1.9.3p194 :002 > 1.class 
=> Fixnum 

Но это правильный способ определить тип объекта?

+0

Да1 рубина это путь ' .class'. –

+0

@iAmRubuuu: Нет, это не так. '# class' возвращает * класс *, а не * тип *. Вот почему он * называется * '# class', в конце концов. ОП спросил о типе, а не о классе. Эти два совершенно разные. –

+0

@DaveNewton: ОП спросил о типе, а не о классе. Эти два совершенно разные. '# class' возвращает * класс *, а не * тип *. –

ответ

402

Правильный способ определения «типа» объекта, который является шатком в мире Ruby, заключается в вызове object.class.

Поскольку классы могут наследовать от других классов, если вы хотите, чтобы определить, является ли объект «конкретного типа» вы могли бы назвать object.is_a?(ClassName), чтобы увидеть, если object имеет тип ClassName или производные от него.

Обычно проверка типа не выполняется в Ruby, но вместо этого объекты оцениваются на основе их способности реагировать на определенные методы, обычно называемые «Duck typing». Другими словами, если он отвечает на нужные вам методы, нет никаких оснований быть конкретными в отношении типа.

Например, object.is_a?(String) является слишком жестким, поскольку другой класс может реализовывать методы, которые преобразуют его в строку, или заставить его вести себя одинаково с тем, как ведет себя String. object.respond_to?(:to_s) - лучший способ проверить, что объект, о котором идет речь, делает то, что вы хотите.

+8

-1. '# class' does * not * возвращает тип объекта, он возвращает свой * класс *. Имя должно быть мертвым поддавки. Класс и тип - это два * полностью * разных понятия в OO. –

+50

@ Jörg W Mittag: Я не согласен. «Класс» и «скорость процессора» (для выбора примера) - это две совершенно разные концепции, но «класс» и «тип» - это тесно связанные понятия. Например, вот что [статья Википедии о классе] (http://en.wikipedia.org/wiki/Class_%28computer_programming%29) гласит: «В объектно-ориентированном программировании класс представляет собой конструкцию, которая используется для определения особый тип ". Тадман помогал допрашивающему. –

+1

@TeemuLeisti: Эта информация просто неверна. Классы определяют * Представления *, Протоколы определяют * Типы *. Определяющей характеристикой Object-Orientation является то, что один тип может иметь несколько представлений, то есть один протокол может предоставляться несколькими классами. Например, в Ruby тип 'IO' * реализуется как классом' IO' *, так и классом 'StringIO' *. Тип 'Enumerable' * * имеет единственный метод' each', тогда как 'Enumerable' * class * (фактически * mixin *) имеет каждый метод * кроме *' each'. –

31

Часто в Ruby вы фактически не заботитесь о том, что класс объекта, по сути, вам просто нужно, чтобы он отвечал на определенный метод. Это называется Duck Typing, и вы увидите его во всех видах кодов Ruby.

Так во многих (если не в большинстве) случаях, его лучше использовать Duck Typing используя #respond_to?(method):

object.respond_to?(:to_i) 
+0

действительный пункт. не отвечает на вопрос, а попадает в суть вопроса. – user566245

50

вы также можете попробовать: instance_of?

p 1.instance_of? Fixnum #=> True 
p "1".instance_of? String #=> True 
p [1,2].instance_of? Array #=> True 
+2

Очень полезное решение во многих ситуациях. Спасибо! – SeattleDucati

6

Я бы сказал: "Да". Как сказал «Мац» в одном из своих разговоров, «Объекты Ruby не имеют типов». Не все, кроме той части, которую он пытается передать нам. Почему кто-нибудь сказал «Все есть объект»? Чтобы добавить, он сказал: «У данных есть типы, а не объекты».

Таким образом, мы можем наслаждаться этим.

https://www.youtube.com/watch?v=1l3U1X3z0CE

Но Руби не заботится много о типе объекта просто класс. Мы используем классы, а не типы. Затем все данные имеют класс.

12345.class 

'my string'.class 

Они могут также иметь предков

Object.ancestors 

Они также имеют мета-классы, но я спасу вас подробности об этом.

Как только вы знаете класс, вы сможете найти, какие методы вы можете использовать для него. Вот где нужен «тип данных». Если вы действительно хотите получить в детали вид вверх ...

«Объектная модель Рубин»

Это термин, используемый для того, как рубин обрабатывает объекты. Это все внутреннее, поэтому вы действительно не видите многое из этого, но приятно знать. Но это еще одна тема.

Да! Класс - это тип данных. Объекты имеют классы, а данные имеют типы. Поэтому, если вы знаете о базах данных, вы знаете, что существует только конечный набор типов.

текстовые блоки номера

+0

Например, 'Object.ancestors # => [Object, Kernel, BasicObject]' – Dorian

Смежные вопросы