有没有办法确定哪个类正在扩展当前模块?

时间:2013-11-20 02:40:32

标签: ruby

说我有这个班:

#outter.rb
class OutterClass
   extend MyModule

   def self.foo
       puts foo
   end
end

然后

#mymodule.rb
module MyModule
  class InnerClass
     def self.foo
        OutterClass.foo  #????? This is the question. How to access OutterClass class?
     end
  end
end

在内部类中,我想调用extender类的方法。如何确定哪个类正在扩展模块?

1 个答案:

答案 0 :(得分:1)

这是你的代码,略有改动:

module MyModule
  def my_method() puts "cat" end
  class InnerClass
    def goo
      foo
    end
  end
end

class OuterClass
  def self.foo
    puts "foo-foo"
  end
end

OuterClass.extend MyModule

OuterClass.my_method # => "cat"
OuterClass.goo       # => undefined local variable or method goo

我将my_method()添加到MyModule,以说明my_method在扩展为包含MyModule方法之后成为OuterClass的类方法。

ExteC没有触及InnerClass(这里只是foo)的(类或实例)方法。正如@Andrew解释的那样,InnerClass刚刚过去了。请注意OuterClass.goo引发异常,因为Ruby无法找到goo。

我从OuterClass中提取OuterClass.extend MyModule以强调扩展将MyModule中的方法与特定对象(此处为OuterClass)相关联。 (您可以在类定义中保留extend MyModule。)我们可以改为(或者)扩展OuterClass的实例:

outer = OuterClass.new
outer.extend MyModule
outer.my_method #=> "cat"

如果希望goo()能够访问foo(),则需要将InnerClass更改为模块(“InnerModule”)。然后你可以把它包含在MyModule中:

module MyModule
  module InnerModule
    def goo
      foo
    end
  end
  include InnerModule
end

class OuterClass
  extend MyModule
  def self.foo
    puts "foo-foo"
  end
end

OuterClass.goo # => "foo-foo"

或添加:

extend MyModule::InnerModule

到OuterClass。以下内容也有效,但在其他情况下更合适:

module MyModule
  def self.extended(mod)
    mod.send(:extend, InnerModule)
  end
  module InnerModule
    def goo
      foo
    end
  end
end

这使用Module#extended挂钩。