5

我会在一个具体的例子上问它(在 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

我错过了什么?

4

2 回答 2

4

“超级”仅存在于“类”上下文中。super 不能生活在“纯模块”上下文中。所以,当你看到这样的代码时:

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!
于 2012-10-14T22:46:28.093 回答
3

我想到了。有一个模块包含在ActionDispatch::Routing::Mapper中,并且该模块包含该#resources方法。如果#resources直接在 上定义ActionDispatch::Routing::Mapper,而不是在模块中,则覆盖它不会以这种方式工作(我们将不得不使用“别名”方法)。

一般来说,关于模块和类,模块就像包含它的类的超类。“表现得像一个超类”我的意思是,如果您#foo在模块上定义了一个方法,并且将该模块包含在一个类中,那么该类可以覆盖该#foo方法,然后调用#super,这将调用该模块的#foo方法。一个例子:

module Foo
  def foo
    puts "foo"
  end
end

class Bar
  include Foo

  def foo
    super
    puts "bar"
  end
end

Bar.new.foo
# foo
# bar
# => nil
于 2012-10-16T00:26:23.630 回答