我有一个字符串,其中包含一个类名。例如,它是一个包含“Article”的字符串。该字符串来自params []。我应该如何处理这个字符串,就好像它是一个类名?例如,我想做:在字符串和类名字之间施放字符串
Article.all
等等。
有什么想法?
我有一个字符串,其中包含一个类名。例如,它是一个包含“Article”的字符串。该字符串来自params []。我应该如何处理这个字符串,就好像它是一个类名?例如,我想做:在字符串和类名字之间施放字符串
Article.all
等等。
有什么想法?
该解决方案优于EVAL你正在评估PARAMS哈希可能由用户来操作,并可能含有对人体有害的行为。作为一般规则:不要直接评估用户输入,这是一个很大的安全漏洞。
# Monkey patch for String class
class String
def to_class
klass = Kernel.const_get(self)
klass.is_a?(Class) ? klass : nil
rescue NameError
nil
end
end
# Examples
"Fixnum".to_class #=> Fixnum
"Something".to_class #=> nil
更新 - 一个更好的版本和命名空间的工作原理:
# Monkey patch for String class
class String
def to_class
chain = self.split "::"
klass = Kernel
chain.each do |klass_string|
klass = klass.const_get klass_string
end
klass.is_a?(Class) ? klass : nil
rescue NameError
nil
end
end
class Abc
end #=> nil
klass = eval("Abc") #=> Abc
klass.new #=> #<Abc:0x37643e8>
假设真的有与所提供的名称类...
在的ActiveSupport,有String#constantize,它也做了同样的事情,但我相信这是2.1后废弃。
编辑:这是constantize从2.1.2的ActiveSupport实施:
def constantize(camel_cased_word)
names = camel_cased_word.split('::')
names.shift if names.empty? || names.first.empty?
constant = Object
names.each do |name|
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
end
constant
end
我不知道我是否正确地理解你的意图。这里我假设all
是一个Article
的类方法,all
返回一组文章。
class Article
def self.all
["Peopleware" , "The Mythical Man-Month"]
end
end
s = "Article"
all_of_article = []
eval("all_of_article = #{s + ".all"}")
puts all_of_article.inspect # ["Peopleware", "The Mythical Man-Month"]
这不会对名称空间类无效,如'MyModule :: MyClass'。为此,你必须分割“::”,然后,例如,使用const_get注入。 – sepp2k 2009-09-19 13:25:54
是的,它需要进一步完善......谢谢! – khelll 2009-09-19 14:04:15
好点。我添加了active_support def,这更符合你的(更好的)建议。 – 2009-09-19 15:41:54