我有一個字符串,其中包含一個類名。例如,它是一個包含「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