ruby string to class

Posted by wxianfeng Wed, 16 Nov 2011 20:53:00 GMT

环境: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