我将在一个具体的例子(在Rails中)问它。在“Destroy without Javascript (revised)”railscast中,Ryan Bates将覆盖#resources
路由方法:
module DeleteResourceRoute
def resources(*args, &block)
super(*args) do
# some code
end
end
end
ActionDispatch::Routing::Mapper.send(:include, DeleteResourceRoute)
但Ruby中的继承不是以模块是“超类”的方式工作的。他怎么能从模块中调用#super
呢?
如果可以覆盖这样的方法,那么人们不会这样做:
class SomeClass
alias old_method method
def method
# ...
old_method
# ...
end
end
可能正在做这件事:
class SomeClass
include Module.new {
def method
# ...
super
# ...
end
}
end
我错过了什么?
答案 0 :(得分:4)
"超"只生活在" class"上下文。超级无法生活在一个纯粹的模块中。上下文。所以,当你看到如下代码时:
module DeleteResourceRoute
def resources(*args, &block)
super(*args) do
# some code
end
end
end
你应该有一个班级来"包括这个模块",然后"超级"生效,例如
class SomeClass extends BaseClass
include DeleteResourceRoute
end
class BaseClass
def resources
puts "called parent!"
end
end
SomeClass.new.resources # => called parent!
答案 1 :(得分:2)
我明白了。 ActionDispatch::Routing::Mapper
中包含一个模块,该模块包含#resources
方法。如果#resources
直接在ActionDispatch::Routing::Mapper
上定义,而不在模块中定义,则覆盖它将无法以这种方式工作(我们将不得不使用“别名”方法)。
关于模块和类,一般来说,模块就像包含它的类的超类一样。通过“表现得像一个超类”,我的意思是,如果你在模块上定义了一个方法#foo
,并且你将该模块包含在一个类中,那么该类可以覆盖#foo
方法,并调用{ {1}},这将调用模块的#super
方法。一个例子:
#foo