Ruby 클래스가 다른 클래스의 서브 클래스인지 테스트


187

클래스가 다른 클래스에서 상속되는지 테스트하고 싶지만 그 방법이 존재하지 않는 것 같습니다.

class A
end

class B < A
end

B.is_a? A 
=> false

B.superclass == A
=> true

내가 원하는 것의 사소한 구현은 다음과 같습니다.

class Class
  def is_subclass_of?(clazz)
    return true if superclass == clazz
    return false if self == Object
    superclass.is_subclass_of?(clazz)
  end
end

그러나 나는 이것이 이미 존재할 것으로 기대합니다.


2
A.class #=> Class. 이것이 B.is_a? A거짓을 반환하는 이유 입니다.
Wen

대해kind_of?
akostadinov

1
kind_of?객체가 클래스 의 인스턴스 인지 테스트합니다 . 객체가 클래스에서 상속되는지 여부가 아닙니다.
혼란

5
kind_of?is_a?
coreyward

답변:


355

그냥 사용 < 연산자를

B < A # => true
A < A # => false

또는 <=연산자를 사용하십시오

B <= A # => true
A <= A # => true

13
@Brian is_a?번역 은의 인스턴스입니다 . B의 인스턴스가 아닌 A, B.new생각한다 ( B.new.is_a? A # => true).
Marcel Jackwerth

4
흠, 이상한 구문 (내가 처음 추측하지 않았을 것임)이지만 설명을 주셔서 감사합니다!
Brian Armstrong

2
설명서는 Core API / 모듈 / # <을 참조하십시오 .
webwurst

2
Ruby와의 사랑 / 증오 관계는 계속됩니다 ... 왜 클래스 관계를 선언하는 데 사용되는 연산자에 다른 기능을 제공하고 두 가지 다른 방법을 제공합니까?
벤 고투

4
@BenGotow-1. <은 연산자가 아니기 때문에 메서드입니다. <는 서브 클래스 만 확인하기 때문에 <=는 self도 포함합니다.
superluminary

59

도 가능:

B.ancestors.include? A

이것은 다음 에 포함되어 B < A있기 때문에 (짧은) 답변과 약간 다릅니다 .BB.ancestors

B.ancestors
#=> [B, A, Object, Kernel, BasicObject]

B < B
#=> false

B.ancestors.include? B
#=> true

이것이 바람직한 지 아닌지는 사용 사례에 따라 다릅니다.


24
더 읽기 : B <= B(와 같은 결과 B.ancestors.include? B)
Marcel Jackwerth

업데이트 : 바로 앞의 솔루션은 1.9 이상에서 작동하지만 "조상은 없습니까?" 1.9에서.

8
이것은 '<'구문에 익숙하지 않은 사람들을 혼동하지 않기 때문에 선호합니다.
Asfand Qazi

2
@SimonLepkin 마이크로 초를 똑딱 거리지 않으면 "아마도"는 아닐 것입니다. ;) 예, 무대 뒤에서 include?and <메소드 는 조상 체인을 통해 반복됩니다 . C 에서이 작업을 수행하므로 Ruby 배열을 반복하는 것보다 빠릅니다. 그러나 실제로 두 가지를 구분할 수는 없습니다.
Phrogz

1
@JunanChakma 영어 단어 "조상"이 어떻게 정의되는지에 따라, 반환 값에 포함하지 않아야한다는 데 동의합니다 B. 그러나 그렇습니다. 이 방법 문서" mod 자신을 포함하여 mod 에 포함 / 추가 된 모듈 목록을 반환합니다" 라고 말합니다 . (강조 광산). 을 사용할 때 편의를 위해 자체 클래스가 포함되어 있다고 생각 .include?하지만 내 추측입니다.
Phrogz
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.