使用.constantize从单独的字符串调用类和方法

时间:2017-10-11 15:03:49

标签: ruby-on-rails ruby

我试图调用一个类和方法,它们都作为字符串存储在数据库中。 我希望从这两个字符串中创建一个对象

class_name = 'Some::Class'
method_name = 'a_method'
params = {foo: 'bar'}

class_name.new(params).method_name

我之前使用过Contantize来采用类似的方法,但我不确定这里最好的解决方案是什么?

由于

4 个答案:

答案 0 :(得分:5)

您可以使用const_get

Class.const_get(class_name).new(params).public_send(method_name)

答案 1 :(得分:2)

class_name.constantize.new(params).send(method_name)应该有用吗?

如果您想使用该方法发送args,您可以使用,例如.send(method_name, params)

如果您从外部来源获取数据,我不确定constantize是多么安全,但它运行顺畅且可读性很好。如果类名的格式可能不同,您也可以使用classify

答案 2 :(得分:0)

您使用ruby-on-rails标记了您的问题,因此我建议使用safe_constantize(仅适用于Rails)和public_send(纯Ruby):

class_name = 'Some::Class'
method_name = 'a_method'
params = {foo: 'bar'}

class_name.safe_constantize.new(params).public_send(method_name)

答案 3 :(得分:0)

如果使用Kernel#eval是安全的,您可以执行以下操作。

module Some
  class Klass
    def initialize(params)
      @params = params
    end
    def a_method
      puts "keys = #{@params.keys}"
    end
  end
end

class_name = 'Some::Klass'
params = { foo: 'bar', oof: 'rab' }
method_name = 'a_method'

str = "%s.new(%s).%s" % [class_name, params, method_name]
  #=> "Some::Klass.new({:foo=>\"bar\", :oof=>\"rab\"}).a_method"
eval str
keys = [:foo, :oof]

这种方法显然有广泛的应用。