2012-01-05 2 views
0

Я хотел бы, чтобы индексировать хэш с классом (не символ!), Как показано на следующемКак получить класс из строки?

irb(main):015:0> class Key ;end 
=> nil 
irb(main):016:0> h={Key => "ok"} 
=> {Key=>"ok"} 

Добра. Тогда, учитывая имя класса, как строка, я хочу, чтобы получить элемент:

irb(main):017:0> str="Key" 
=> "Key" 
irb(main):018:0> h[str] 
=> nil 

Но (как показано выше) это не удается (конечно).

Итак, мой вопрос: как я могу преобразовать строку в фактический класс?

+0

возможно дубликат [Cast между струнных и Classname] (http://stackoverflow.com/questions/1448293/cast-between-string-and-classname) –

ответ

3

Вы можете использовать Kernel#const_get:

str = "Key" 
k = Kernel.const_get(str) 
val = h[k] 
-3

вы можете использовать h[eval(str)]. Дополнительная информация о eval in the Ruby 1.9.3 docs

Я должен добавить, что это острый нож, не режусь на эту технику. Вы хотите удостовериться, что строка, которую вы eval'ing, не может содержать вредоносный код.

+0

Я не думаю, что мы должны советовать людям использовать 'eval', если это не необходимо. В этом случае его определенно не нужно. –

+0

Справедливая критика, есть и другие способы решения этой проблемы. –

6

Если вы используете Rails, то вы найдете «constantize» ActiveSupport, чтобы делать то, что вы хотите.

"String".constantize 
=> String 

Но вы можете сделать что-то подобное.

Object.const_get("String") 
=> String 

Вы даже можете определить это на строку

class String 
    def constantize 
    Object.const_get(self) 
    end 
end 

Примечание: старайтесь избегать делать «Eval», если вам действительно не нужно.

0

Вы можете сделать это следующим образом (вы, вероятно, не хотите использовать eval):

>> class Key ;end #=> nil 
>> h={Key => "ok"} #=> {Key=>"ok"} 
>> str="Key" #=> "Key" 
>> h[Kernel.const_get(str)] #=> "ok" 
Смежные вопросы