Khi gọi method, Ruby tìm theo thứ tự: object eigenclass → class → prepended modules (LIFO) → included modules (LIFO) → superclass và cứ thế leo lên đến BasicObject.
module M1; def hello = "M1"; end
module M2; def hello = "M2"; end
class Base
def hello = "Base"
end
class Child < Base
include M1
include M2 # include sau → cao hơn trong chain
end
Child.ancestors
# => [Child, M2, M1, Base, Object, Kernel, BasicObject]
Child.new.hello # => "M2" — M2 được tìm thấy trướcprepend chèn module trước class trong chain, include chèn sau class (trước superclass).
Hình dung: ancestors là danh sách ưu tiên tra cứu — phần tử đầu tiên có method phù hợp thắng.
When a method is called, Ruby searches: object eigenclass → class → prepended modules (LIFO) → included modules (LIFO) → superclass, all the way up to BasicObject.
module M1; def hello = "M1"; end
module M2; def hello = "M2"; end
class Base
def hello = "Base"
end
class Child < Base
include M1
include M2 # included last → higher in chain
end
Child.ancestors
# => [Child, M2, M1, Base, Object, Kernel, BasicObject]
Child.new.hello # => "M2"prepend inserts a module before the class; include inserts it after the class (before the superclass).
Mental model: ancestors is the priority lookup list — the first entry with a matching method wins.