如何动态创建也在命名空间中的子类?

时间:2013-01-25 03:01:33

标签: ruby namespaces metaprogramming subclass

我正在研究一个用于RESTful API的gem,我注意到,因为它是一个REST api,所以很多资源URL是相同的,因此每个类的几个方法将完全相同(只是uri路径不同)。

我开始创建这样的类:

module NameSpace
 Class1 < SuperClass; ... end
end
各种文件中的

同样如下:

moduel NameSpace
 Class2 < SuperClass; ... end
end

所以,这是我迄今为止开发的内容:

    RESOURCE_NAMES = [
      "Class1",
      "Class2",
       ...
    ]

module NameSpace
 RESOURCE_NAMES.each {|class_name|
     Object.const_set(
        class_name,
        Class.new(SuperClass) do
          CONTROLLER = class_name.downcase

          @attributes = {}

          # class variables
          def self.show(id); ... end
          def self.update(id); ... end
          def self.destroy(id); ... end

        end
     )
  }
end

但是当我尝试运行控制台并需要我的宝石时,我得到了这个输出:

require "rubygems"

require "mygem"
/home/me/.rvm/gems/ruby-1.8.7-p371/gems/mygem-0.0.1/lib/mygem/restful_resource.rb:17: warning: already initialized constant CONTROLLER
/home/me/.rvm/gems/ruby-1.8.7-p371/gems/mygem-0.0.1/lib/mygem/restful_resource.rb:17: warning: already initialized constant CONTROLLER
/home/me/.rvm/gems/ruby-1.8.7-p371/gems/mygem-0.0.1/lib/mygem/restful_resource.rb:17: warning: already initialized constant CONTROLLER
/home/me/.rvm/gems/ruby-1.8.7-p371/gems/mygem-0.0.1/lib/mygem/restful_resource.rb:17: warning: already initialized constant CONTROLLER
/home/me/.rvm/gems/ruby-1.8.7-p371/gems/mygem-0.0.1/lib/mygem/restful_resource.rb:17: warning: already initialized constant CONTROLLER

当我尝试做的时候 > NameSpace::Cass1,我得到

 NameError: uninitialized constant NameSpace::Class1

我的问题是:我关闭了吗?如何正确定义动态子类和命名空间类?

2 个答案:

答案 0 :(得分:2)

使用const_set设置CONTROLLER常量似乎有效:

const_set :CONTROLLER, class_name.downcase

对于另一个问题,您应该将Object.const_set(更改为const_set(,这将在您的NameSpace模块中按照您希望的方式设置常量。

答案 1 :(得分:-1)

考虑一下这个?

module NameSpace

  class SuperClass
  end

  RESOURCE_NAMES = %w[ Class1 Class2 Class3 Class4 ]

  RESOURCE_NAMES.each do |class_name|
    eval( "class #{ class_name } < SuperClass ; end" )
  end

end