Tôi đã đọc một vài bài viết về các phương thức mixin của Ruby, extend
và include
và tôi vẫn chưa hoàn toàn chắc chắn về hành vi. Tôi hiểu rằng extend
sẽ thêm các phương thức thể hiện của mô-đun đã cho làm phương thức singleton cho mô-đun đang mở rộng và include
về cơ bản sẽ thêm nội dung của mô-đun (phương thức, hằng số, biến) vào mô-đun. chúng trong máy thu.Ruby mixins: mở rộng và bao gồm
Tuy nhiên, sau khi một số tinkering, cố gắng để có được một cảm giác về cách hành vi sẽ biểu hiện, tôi đã có một vài câu hỏi. Đây là thiết lập thử nghiệm của tôi:
module Baz
def blorg
puts 'blorg'
end
end
module Bar
include Baz
def blah
puts 'blah'
end
end
module Foo
extend Bar
end
class Bacon
extend Bar
end
class Egg
include Bar
end
Vì vậy, như tôi mong đợi, mô-đun Bar
tăng các phương pháp dụ quy định tại Baz
(#blorg
), nếu như họ muốn được định nghĩa trong tự do phương pháp bao gồm, và lớp Bacon
lợi nhuận các phương thức singleton Bacon::blah
và Bacon::blorg
theo tiện ích.
Bacon.blah # => blah
Bacon.blorg # => blorg
Và lớp Egg
tăng các phương pháp quy định tại Bar
(#blah
và bây giờ #blorg
) như các phương pháp dụ.
Egg.new.blah # => blah
Egg.new.blorg # => blorg
Tôi nhận được tất cả những điều đó, vì vậy tốt.
Tuy nhiên, tôi không hiểu các câu trả lời tôi nhận được từ việc sử dụng các phương pháp #ancestors
và #is_a?
.
Bacon.ancestors # => [Bacon, Object, Kernel, BasicObject]
Bacon.is_a? Bar # => true
Egg.ancestors # => [Egg, Bar, Baz, Object, Kernel, BasicObject]
Egg.is_a? Bar # => false
Có vẻ như rằng việc mở rộng một mô-đun làm cho #is_a?
phương pháp để trở true
khi được hỏi về mô-đun đó, nhưng nó không được thêm vào tổ tiên của lớp, và ngược lại liên quan đến bao gồm: tổ tiên của lớp chứa các mô-đun được bao gồm, nhưng phương thức #is_a?
trả về false
khi được truy vấn. Lý do tại sao điều này xảy ra?
+1 cho định dạng tuyệt vời của câu hỏi này. – sargas