Ruby符号到类

时间:2009-08-05 20:37:16

标签: ruby class transform symbols

Ruby中是否有一种方法可以使用符号或字符串并将其转换为同名的类?

例如,如果我有一个类,如

class Bob
  def talk
     puts "Hi, I'm bob"
  end
end

我在代码中的其他地方的方法传递了一个符号:bob,我能以某种方式将其转换为类Bob吗?也许像是

b = :Bob.new
b.talk

或者有没有办法做类似的事情?

7 个答案:

答案 0 :(得分:53)

有很多方法可以做到这一点。缺乏背景使得无法选择“最佳”方式。这里有几个。

Kernel.const_get(:Bob)

eval(:Bob.to_s)

Kernel.const_get(:bob.to_s.capitalize)

答案 1 :(得分:40)

滑轨

仅用于Rails。

使用字符串:

"Module".constantize #=> Module
"Class".constantize #=> Class

带有符号:

:module.to_s.classify.constantize #=> Module
:open_struct.to_s.classify.constantize #=> OpenStruct

如果您正在处理多字符号,那么您需要将#classify添加到链中以正确处理常量的所有部分的大写。< / p>

http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-constantize

答案 2 :(得分:10)

如果你想转向,我见过的解决方案都没有工作:foo_bar进入FooBar。如果这就是你要找的东西:

  

:foo_bar.to_s.split( “_”)收集(安培;:大写)。.join.constantize
  =&GT; FooBar

希望能有所帮助。

答案 3 :(得分:5)

NameSpace.const_get(classname)将返回类对象(假设classname包含类的名称 - 如果它包含不是类的常量的名称,它将返回该常量的值)。顶级命名空间是Object,因此您可以执行Object.const_get(:Bob).new

答案 4 :(得分:3)

class Bob
end

def create(name)
  return eval("#{name}.new")
end

b = create(:Bob)
puts b.class

答案 5 :(得分:2)

这是我在寻找包含模块/名称空间支持的类似内容时提出的:

['foo', 'bar'].inject {|r,e| "#{r.classify}::#{e.classify}"}.constantize

可生产

=> Foo::Bar

然而,这需要Rails,当然它只适用于数组有多个元素的地方。

这看起来相当简单,所以我肯定我错过了一些东西,有人会关心为什么这不是一个好方法吗?

谢谢!

答案 6 :(得分:0)

在我的情况下,下面的示例都有效,但您也不必忘记命名空间:

  Object.const_get("ModuleName::#{class_model_name}")

  Kernel.const_get("ModuleName::#{class_model_name}").