如何在模块中使用动态选择的类

时间:2011-07-28 08:58:30

标签: ruby-on-rails ruby shopify

我很确定这是一个无用的标题......抱歉。

我希望能够将Class传递给方法,然后使用该类。这是一个简单,有效的例子:

def my_method(klass)
  klass.new
end

使用:

>> my_method(Product)
=> #<Product id:nil, created_at: nil, updated_at: nil, price: nil>
>> my_method(Order)
=> #<Order id:nil, created_at: nil, updated_at: nil, total_value: nil>

无法工作的是尝试在模块上使用klass变量:

>> ShopifyAPI::klass.first
=> NoMethodError: undefined method `klass' for ShopifyAPI:Module

我是否尝试过一项不可能完成的任务?任何人都可以对此有所了解吗?

干杯

2 个答案:

答案 0 :(得分:3)

首先,我认为这不是不可能

当然,没有为模块定义klass方法&lt; - 这是正确的,因为ShopifyAPI.methods.include? "klass" # => false

但是,类是模块中的常量。模块有一个constants方法,您可以使用它来检索类。这个方法的问题是它还检索非类的模块中的常量。

我想出了解决问题的方法

# get all the classes in the module
klasses = ShopifyAPI.constants.select do |klass|
    ShopifyAPI.const_get(klass).class == Class
end

# get the first class in that list
klasses.first

答案 1 :(得分:0)

你也可以使用module_eval:

ShopifyAPI.module_eval {klass}.first

希望我的问题是正确的:)

irb(main):001:0> module ShopifyAPI
irb(main):002:1> class Something
irb(main):003:2> end
irb(main):004:1> end
=> nil
irb(main):005:0> klass = ShopifyAPI::Something
=> ShopifyAPI::Something
irb(main):006:0> ShopifyAPI::klass
NoMethodError: undefined method `klass' for ShopifyAPI:Module
        from (irb):6
        from C:/Ruby192/bin/irb:12:in `<main>
irb(main):007:0> ShopifyAPI.module_eval {klass}
=> ShopifyAPI::Something
irb(main):008:0>