2009-09-19 103 views
1

我有一個字符串,其中包含一個類名。例如,它是一個包含「Article」的字符串。該字符串來自params []。我應該如何處理這個字符串,就好像它是一個類名?例如,我想做:在字符串和類名字之間施放字符串

Article.all 

等等。

有什麼想法?

回答

4

該解決方案優於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 
+2

這不會對名稱空間類無效,如'MyModule :: MyClass'。爲此,你必須分割「::」,然後,例如,使用const_get注入。 – sepp2k 2009-09-19 13:25:54

+0

是的,它需要進一步完善......謝謝! – khelll 2009-09-19 14:04:15

+0

好點。我添加了active_support def,這更符合你的(更好的)建議。 – 2009-09-19 15:41:54

3
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 
+1

這是一個有點危險使用eval爲PARAMS原因它可能包含有害代碼。我不推薦這個解決方案 – khelll 2009-09-19 11:13:18

+0

哇!非常感謝! – gmile 2009-09-19 11:13:42

+0

khell,任何安全的解決方案? – gmile 2009-09-19 11:14:15

0

我不知道我是否正確地理解你的意圖。這裏我假設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"] 
相關問題