Ruby 为什么extend方法不重视看跌期权
我原以为我会看到的Ruby 为什么extend方法不重视看跌期权,ruby,inheritance,Ruby,Inheritance,我原以为我会看到的 module Lab def self.foo puts 'foo from lab' end end module M def foo puts 'foo from module' super end end module Lab extend M end Lab.foo 然而,我得到的是 foo from module foo from lab 我试图做的是从gem截取一个方法的值并做一些事情。我可以使用alias_m
module Lab
def self.foo
puts 'foo from lab'
end
end
module M
def foo
puts 'foo from module'
super
end
end
module Lab
extend M
end
Lab.foo
然而,我得到的是
foo from module
foo from lab
我试图做的是从gem截取一个方法的值并做一些事情。我可以使用alias_method_chain,但我尝试不使用它。当您将模块
M
包含/扩展到类C
,并调用方法C#method
或C.method
时,则C
在方法的搜索路径中优先于M
。换句话说,不能通过include/extend覆盖方法。只能添加新方法。见相关问题
在您的例子中,只需调用Lab.foo
。以下内容(不带Lab.foo
)将为您提供所需的结果
foo from lab
请注意,M
的超类是Module
,由于未定义Module#foo
,以下内容将导致错误
module M
def foo
puts 'foo from module'
end
end
module Lab
extend M
end
Lab.foo
# => foo from module
如果你在期待
module M
def foo
puts 'foo from module'
super
end
end
module Lab
extend M
end
Lab.foo
# => method undefined error
然后你需要把super放在Lab#foo里,就像这样:
foo from module
foo from lab
Lab
上定义的方法直接优先于Lab
扩展的M
等模块中定义的方法
因此,直接在Lab
上定义的foo
优先于M#foo
,即使Lab.extend M
要获得您想要的,请执行以下操作:
module Lab
def self.foo
super
puts 'foo from lab'
end
end
module M
def foo
puts 'foo from module'
end
end
module Lab
extend M
end
Lab.foo
我删除了我的答案,因为它是不正确的(而且出于某种原因,人们无论如何都在投票)。为了避免人们像我想的那样思考:上面代码中的两个方法都不是实例方法(因为
extend
是如何工作的)。
module Lab
module HasFoo
# foo isn't defined directly on Lab directly anymore;
# instead, it is defined in a separate module that
# Lab extends
def foo
puts "foo from lab"
end
end
extend HasFoo
end
module M
def foo
puts "foo from module"
super
end
end
module Lab
# when Lab extends another module with foo, that changes
# which concrete method the name foo gets resolved to
extend M
end
# now you should see the module foo and then the lab foo
Lab.foo