2017-10-11 44 views
2

我试图调用一个类和方法,它们都作为字符串存储在数据库中。 我将寻求建立 使用.constantize从单独的字符串调用类和方法

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

class_name.new(params).method_name 

我以前用过Contantize的类似的方法从这些2串

的对象,但我不知道到底最好的解决办法是什么吗?

感谢

回答

5

您可以使用const_get

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

通常'Object.const_get'用于获取顶级常量。 – Stefan

2

class_name.constantize.new(params).send(method_name)应该工作?

如果你想用的方法来发送指定参数时,您可以使用,例如,.send(method_name, params)

如果您收到来自外部源的数据,我不知道怎么constantize安全的,但它的工作原理顺利,很好可读。如果类名称的格式可能有所不同,您也可以使用classify

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) 
+2

是什么原因? 'NameError'(constantize)vs'NoMethodError'(safe_constantize)?国际海事组织,“NameError”更清晰。 – Ilya

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] 

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