在字符串和类名之间进行转换

发布于 2024-08-05 16:12:08 字数 152 浏览 2 评论 0原文

我有一个字符串,其中包含类名。例如,它是包含“Article”的字符串。该字符串来自 params[]。我应该怎么做才能像类名一样使用这个字符串?比如我想做:

Article.all

等等。

有什么想法吗?

I have a string, containing an Class name. It is, for example, a string containing "Article". That string came up from the params[]. What should I do to work with this string as if it was a class name? For instance, I want to do:

Article.all

and so on.

Any idea?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浅笑轻吟梦一曲 2024-08-12 16:12:08

此解决方案比 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

This solution is better than eval as you are evaluating params hash that might be manipulated by the user and could contain harmful actions. As a general rule: Never evaluate user input directly, that's a big security hole.

# 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

Update - a better version that works with namespaces:

 # 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
空心↖ 2024-08-12 16:12:08
class Abc
end #=> nil
klass = eval("Abc") #=> Abc
klass.new #=> #<Abc:0x37643e8>

假设确实存在一个提供名称的类...

在 ActiveSupport 中,有 String#constantize,它做了同样的事情,但我相信它在 2.1 之后已被弃用。

编辑:这是 ActiveSupport 2.1.2 中的 Constantize 实现:

  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
class Abc
end #=> nil
klass = eval("Abc") #=> Abc
klass.new #=> #<Abc:0x37643e8>

Assumes there really is a class with the name provided...

In ActiveSupport, there was String#constantize, which did the same thing, but I believe it's deprecated after 2.1.

EDIT: this is the implementation of constantize from ActiveSupport 2.1.2:

  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
羅雙樹 2024-08-12 16:12:08

我不确定我是否正确理解了你的意图。这里我假设 allArticle 的类方法,并且 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"]

I am not sure whether I understand your intention correctly. Here I assume all is an Class method of Article and all return an array of articles.

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"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文