在Ruby中按名称获取类?

有一个string与模块和类的名称,如:

"Admin::MetaDatasController" 

我如何获得实际的课程?

如果没有模块,以下代码可以工作:

 Kernel.const_get("MetaDatasController") 

但它打破了模块:

 ruby-1.8.7-p174 > Kernel.const_get("Admin::MetaDatasController") NameError: wrong constant name Admin::MetaDatasController from (irb):34:in `const_get' from (irb):34 ruby-1.8.7-p174 > 

如果你想要简单的处理你的特殊情况,你可以写

 Object.const_get("Admin").const_get("MetaDatasController") 

但是如果你想要更通用的东西,就把:: string上的string分开,并依次parsing名字:

 def class_from_string(str) str.split('::').inject(Object) do |mod, class_name| mod.const_get(class_name) end end the_class = class_from_string("Admin::MetaDatasController") 

在第一次迭代中, Object被要求input常量Admin并返回Admin模块或者类,然后在第二次迭代时,模块或者类被要求input常量MetaDatasController ,并且返回那个类。 由于没有更多的组件从该方法返回类(如果有更多的组件,它会迭代,直到find最后一个)。

ActiveSupport提供了一个名为constantize的方法,它可以做到这一点。 如果你在Rails上,我假设你基于你的常量的名字,那么你已经加载了ActiveSupport。

 require 'active_support/core_ext/string' class Admin class MetaDatasController end end "Admin::MetaDatasController".constantize # => Admin::MetaDatasController 

要了解如何实现该方法,请查看https://github.com/rails/rails/blob/85c2141fe3d7edb636a0b5e1d203f05c70db39dc/activesupport/lib/active_support/inflector/methods.rb#L230-L253

在Ruby 2.x中,你可以这样做:

 Object.const_get('Admin::MetaDatasController') => Admin::MetaDatasController 

我可以离开基地,但不会eval返回类?

 eval("Admin::MetaDatasController") 

所以eval("Admin::MetaDatasController").new将是相同的Admin::MetaDatasController.new