环境:ruby 1.9.2
有这样一个需求, 给你 任意一个字符串,把它转化为类,网上大多数的 解决办法是 下面三种:
Kernel.const_get(:User) # Object.const_get(:User) eval(’User’) ‘User’.constantize
但是上面三种方法, 这个 User 事先必须是初始化的,不然会报错,如下:
Object.const_get(:User) # uninitialized constant User (NameError)
所以需要加个判断 这个 Class 有没有初始化,没有的话 再set 一个Class
require "rails/all" def Kernel.const_missing(name) Object.const_set(name,Class.new) end #p Kernel.const_get("baoxiaos".to_sym) # wrong constant name baoxiaos (NameError) p Kernel.const_get("baoxiaos".classify.to_sym) # Baoxiao , const的首字母必须大写 p Kernel.constants # [] p Object.constants.include?(:UBaoxiao) # true
刚开始把这个 const 定义在 Object 里:
require "rails/all" def Object.const_missing(name) Object.const_set(name,Class.new) end #p Object.const_get("baoxiaos".to_sym) # wrong constant name baoxiaos (NameError) p Object.const_get("baoxiaos".classify.to_sym)
发现 用在 rails 中后 , rails 处处报错,可能 怪我重写了 Object.const_missing 导致的 ……..
上面方法的原理是 当找不到 const的时候 执行了
Object.const_set(name,Class.new)
那么 name 就变成是 Class 的实例了 , 为什么定义在 Kernel 中的 const_missing ,Object 也可以访问到,需要注意 Object,Kernel 之间的关系,Object 是 inluce Kernel 的,如下:
class Object include Kernel end
SEE:
http://niczsoft.com/2010/01/string-to-class-in-ruby-on-rails/
http://www.ruby-forum.com/topic/96222