2010-10-08 1 views
403

В чем разница? Когда я должен использовать это? Почему их так много?Рубин: kind_of? vs. instance_of? vs. is_a?

+17

Как, почему и 'is_a?' и 'kind_of?' существуют: я полагаю, что это часть философии дизайна Ruby. Python сказал бы, что должен быть только один способ сделать что-то; Ruby часто имеет синонимичные методы, поэтому вы можете использовать тот, который звучит лучше. Это вопрос предпочтения. Частично это может быть связано с влиянием Японии: мне говорят, что они будут использовать другое слово для одного и того же номера в зависимости от предложения, чтобы сделать его более приятным. Мац, возможно, несла эту идею в свой языковой дизайн. –

+0

@ NathanLong Я не думаю, что японские счетчики имеют к этому много общего; все языки имеют какое-то соглашение, и вы не можете заменить один счетчик на другое время (например, вы не можете использовать счетчик цилиндров для плоских объектов, это просто неправильно). И это больше связано с семантикой, чем с эвфонией. – Casey

ответ

520

kind_of? и is_a? являются синонимами. instance_of? отличается от двух других тем, что он возвращает только true, если объект является экземпляром этого точного класса, а не подкласса.

Пример: "hello".is_a? Object и "hello".kind_of? Object возвращение true, потому что "hello" является String и String является подклассом Object. Однако "hello".instance_of? Object возвращает false.

+0

ah is 'is_a?' Только для обратной совместимости тогда? – Claudiu

+71

Он иногда лучше читает. Подумайте, '@ honda.kind_of? Car' и '@ person.is_a? Администратор, Ruby - все об эстетике. Фактически, обратите внимание на грамматическую ошибку ... с активной поддержкой вы можете написать '@ person.is_an? Administrator':) ... Наверное, это могло бы превратиться в ядро ​​Ruby. – rfunduk

+2

Хех это интересная причина. можешь ли ты сломать это, ты? как вы можете переопределить 'kind_of? ', но не' is_a? '? – Claudiu

14

В чем разница?

Из документации:

- ( булевы) instance_of?(class)
Возвращает true если obj является экземпляром данного класса.

и:

- ( булевы) is_a?(class)
- ( булевы) kind_of?(class)
Возвращает true если class является класс obj, или если class является одним из суперклассы obj или модули, включенные в obj.

Если что неясно, было бы неплохо знать, что именно неясны, так что документация может быть улучшена.

Когда следует использовать какой?

Никогда. Вместо этого используйте полиморфизм.

Почему их так много?

Я бы не позвонил два «много». Их два, потому что они делают две разные вещи.

+3

Я думаю, что мое замешательство в том, что есть 3, и что 2 просто делают то же самое и имеют разные имена. Об использовании полиморфизма - согласен, но рубиновая стандартная библиотека полна использования каждого из них. – Claudiu

+4

Что вы подразумеваете под полиморфизмом? Это то же самое, что и утиная печать? –

+1

Да, они такие же. Утиная печать - это форма полиморфизма. – SpaceGhost

5

Это похоже на Ruby-like, чтобы спросить объекты, отвечают ли они на какой-либо метод или нет, используя respond_to?. Это позволяет как минимальному интерфейсу, так и реализации выполнять нестандартное программирование.

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

+5

Это зависит от ситуации. Оба комментария и блог могут отвечать на created_at. В такой ситуации is_a? более подходит IMHO – penkovsky

3

я бы не назвал два многих (is_a? и kind_of? являются псевдонимами одного и того же метода), но если вы хотите увидеть больше возможностей, обратить внимание на #class метод:

A = Class.new 
B = Class.new A 

a, b = A.new, B.new 
b.class < A # true - means that b.class is a subclass of A 
a.class < B # false - means that a.class is not a subclass of A 
# Another possibility: Use #ancestors 
b.class.ancestors.include? A # true - means that b.class has A among its ancestors 
a.class.ancestors.include? B # false - means that B is not an ancestor of a.class 
+1

Спасибо - я действительно спрашивал в общем смысле, «какая информация типа времени выполнения может быть собрана в Ruby и как» - и это дает достаточно примеров – Claudiu

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

  • Нет связанных вопросов^_^