字符串和类名之间进行转换(Cast between String and Classname)

2019-07-18 14:48发布

我有一个字符串,包含类的名称。 这是,例如,含有“条”的字符串。 该字符串从PARAMS []走了过来。 我应该怎么做与该字符串的工作,如果它是一个类的名字? 举例来说,我想做的事:

Article.all

等等。

任何的想法?

Answer 1:

该解决方案是因为你正在评估可能会被用户操作,并可能含有对人体有害的行动PARAMS哈希比EVAL更好。 作为一般的规则: 不要直接评估用户的输入,这是一个很大的安全漏洞。

# 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


Answer 2:

class Abc
end #=> nil
klass = eval("Abc") #=> Abc
klass.new #=> #<Abc:0x37643e8>

假设真的有与所提供的名称的类...

在的ActiveSupport,有串#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


Answer 3:

我不知道我是否正确地理解你的意图。 在这里,我承担all是一个类的方法Articleall返回的物品的排列。

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"]


文章来源: Cast between String and Classname