Kiểm tra xem một lớp Ruby có phải là một lớp con của một lớp khác không


187

Tôi muốn kiểm tra xem một lớp có kế thừa từ một lớp khác không, nhưng dường như không tồn tại một phương thức cho điều đó.

class A
end

class B < A
end

B.is_a? A 
=> false

B.superclass == A
=> true

Một triển khai tầm thường của những gì tôi muốn sẽ là:

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

nhưng tôi hy vọng điều này đã tồn tại


2
A.class #=> Class. Đây là lý do tại sao B.is_a? Atrả về sai.
Ôn

những gì vềkind_of?
akostadinov

1
kind_of?kiểm tra xem một đối tượng là một thể hiện của một lớp. Không phải là đối tượng kế thừa từ một lớp.
Nhầm lẫn

5
kind_of?là bí danh củais_a?
coreyward

Câu trả lời:


355

Chỉ cần sử dụng <toán tử

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

hoặc sử dụng <=toán tử

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

13
@Brian Vì is_a?dịch là ví dụ của . Bkhông phải là một ví dụ của A, B.newmặc dù ( B.new.is_a? A # => true).
Marcel Jackwerth

4
Hmm, cú pháp lạ (sẽ không phải là phỏng đoán đầu tiên của tôi), nhưng cảm ơn vì đã làm rõ!
Brian Armstrong

2
Để biết tài liệu, hãy xem Core API / Module / # < .
webwurst

2
Mối quan hệ yêu / ghét của tôi với Ruby vẫn tiếp tục Tại sao lại cung cấp một chức năng khác cho một toán tử được sử dụng để khai báo các mối quan hệ lớp VÀ cung cấp hai cách khác nhau để thực hiện?
Ben Gotow

4
@BenGotow - 1. Vì <không phải là toán tử, nên nó là một phương thức. 2. Vì <chỉ kiểm tra một lớp con và <= cũng bao gồm cả bản thân.
siêu sáng

59

Cũng có sẵn:

B.ancestors.include? A

Điều này hơi khác với câu trả lời (ngắn hơn) B < ABđược bao gồm trong B.ancestors:

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

B < B
#=> false

B.ancestors.include? B
#=> true

Điều này có được mong muốn hay không phụ thuộc vào trường hợp sử dụng của bạn.


24
Dễ đọc hơn: B <= B(kết quả tương tự như B.ancestors.include? B).
Marcel Jackwerth

Cập nhật: Giải pháp ngay trước đó hoạt động với 1.9+ trong khi không có "tổ tiên?" trong 1.9.

8
Điều này sẽ không gây nhầm lẫn cho những người không quen thuộc với cú pháp '<' và vì lý do đó tôi thích nó.
Asfand Qazi

2
@SimonLepkin Có lẽ không phải là "một lúc", trừ khi bạn có thể trải nghiệm tích tắc trong vài giây. ;) Có, đằng sau hậu trường include?<các phương thức lặp qua chuỗi tổ tiên . Nó thực hiện điều này trong C, vì vậy chắc chắn nhanh hơn việc lặp qua mảng Ruby ... nhưng thực tế cả hai không thể phân biệt được.
Phrogz 10/07/2015

1
@JunanChakma Dựa trên cách định nghĩa từ tiếng Anh "tổ tiên", tôi đồng ý rằng giá trị trả lại không nên bao gồm B. Nhưng nó làm. Các tài liệu hướng dẫn phương pháp nói, "Trả một danh sách các module bao gồm / prepended trong mod ( kể cả mod bản thân )." (nhấn mạnh của tôi). Tôi đoán nó bao gồm lớp riêng của nó để thuận tiện khi sử dụng .include?, nhưng đó chỉ là suy đoán của tôi.
Phrogz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.