【问题标题】:Create a class at run time within a module/namespace在运行时在模块/命名空间中创建一个类
【发布时间】:2012-06-25 23:22:52
【问题描述】:

在运行时创建一个类的过程如下:

klass = Class.new superclass, &block
Object.const_set class_name, klass

例子:

class Person
  def name
    "Jon"
  end
end

klass = Class.new Person do
  def name
    "#{super} Doe"
  end
end

Object.const_set "Employee", klass

puts Employee.new.name # prints "Jon Doe"

现在,假设您有一个名为 Company 的模块:

module Company
end

您如何在 Company 模块/命名空间中在运行时创建 Employee 类,以便以下产生相同的结果?

puts Company::Employee.new.name # prints "Jon Doe"

【问题讨论】:

    标签: ruby class module namespaces runtime


    【解决方案1】:

    你已经拥有了所有必要的部分:

    class Person
      def name
        "Jon"
      end
    end
    
    klass = Class.new Person do
      def name
        "#{super} Doe"
      end
    end
    
    module Company
    end
    
    Company.const_set "Employee", klass
    
    puts Company::Employee.new.name # prints "Jon Doe"
    
    Company.constants.grep(/Emp/)
    #=> [:Employee]
    

    【讨论】:

      【解决方案2】:

      比你想象的要容易:)

      Company.const_set "Employee", klass
      

      当您在Object 上设置某些内容时,它会变成全局的,因为,嗯,一切都是Object。但是您可以对每个类/模块执行const_set。请记住,模块/类只是常量。所以,Company::Employee 是常量Employee 中的常量Company。很简单:)

      完整代码:

      class Person
        def name
          "Jon"
        end
      end
      
      klass = Class.new Person do
        def name
          "#{super} Doe"
        end
      end
      
      module Company
      end
      
      Company.const_set "Employee", klass
      
      Company::Employee.new.name # => "Jon Doe"
      

      【讨论】:

      • 比你快 2 秒 :p
      • @MichaelKohl:是的,我用它们来剪切/粘贴那条线 :)
      • 感谢塞尔吉奥的回答和解释!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-14
      • 2014-04-26
      • 2012-05-27
      相关资源
      最近更新 更多