【问题标题】:Get the referred object of a Ruby variable获取 Ruby 变量的引用对象
【发布时间】:2016-01-08 10:10:10
【问题描述】:

我正在做一个任务,我得到一组类(更准确地说是 ActiveRecord 类),我想得到它们的名字。我通过迭代这个集合并将#name 之类的方法应用于集合的元素来做到这一点。 像这样的:

array_of_classes.map {|class| class.name}

问题是这个数组中的一些元素没有初始化,所以当我对它们调用#name 时,我得到:

NameError: uninitialized constant ClassName

要了解变量或常量是否已被初始化,我可以使用 defined?keyword,如下所示:

> defined? UnInitializedClass
nil
> defined? InitializedClass
"constant"

问题在于,当我们有一个 已初始化和未初始化元素的数组并且我们遍历数组以获取它们的元素时,事情会变得更加复杂。 defined? 关键字将应用于迭代器本身,而不是应用于这些变量指向的类(或常量或变量)。

> [UnInitializedClass, InitializedClass ].map {|x| defined? x}
["local-variable", "local-variable"]

有没有办法将defined? 关键字应用于constant 变量x 持有?

如果没有,您知道如何找出 Ruby 数组中未初始化的元素吗?

另一个想法可能是使用方括号方法[] 访问每个元素,但defined? 仍然没有应用于引用的常量

> defined? array[0]
"method"
> defined? array[1]
"method"

【问题讨论】:

  • 定义数组怎么不炸?如果我尝试[Asdf],我会在开始尝试迭代之前立即得到NameError: uninitialized constant Asdf
  • 我不是自己创建的。它是我在模型上调用 #reflect_on_all_associations 时创建的。
  • 急切加载类应该可以解决所有这些问题(模型类将全部加载)
  • 问题是导致问题的类已经从项目中移除了。
  • 问题是导致问题的类已从项目中删除,但由于某种原因#reflect_on_all_associations 方法仍在返回它。

标签: ruby-on-rails arrays ruby class activerecord


【解决方案1】:

我不确定如何拥有一个常量数组,其中一些未定义...但是,您可以使用救援块来过滤掉有效的常量。

array_of_classes = 
  array_of_classes.each_with_object([]) { |klass, acc|
    begin
      klass
    rescue NameError
      # Do nothing
    else
      acc << klass
    end
  }

之后,您应该可以安全地照常使用常量了。

【讨论】:

  • 成功了!也许这不是最优雅的解决方案,但它对我有用。
  • 我们可以看一个例子吗?我认为不是,因为你在开场白中给出的原因。如果数组是[A,B] 并且B 没有被定义,你会立即得到一个语法错误(即没有被挽救)。此外,如果AB 都已定义,但A #=&gt; 'cat' 怎么办?
【解决方案2】:

或 pdobb 代码的更短版本:

array_of_classes.map {|klass| klass.name rescue nil}.compact

【讨论】:

  • 缩短版本的错误代码并不是一种改进。
  • 卡里,OP 提到“有效!”在他对 pdobb 回答的评论中。
【解决方案3】:

这个问题有意义的唯一方法是数组不包含常量和未初始化的常量(后者会立即引发语法错误),而是包含已初始化未初始化类的名称的字符串。在这种情况下,您可以这样做:

class A
end 
B = 'cat'

['A','B','C'].select do |s|
  Object.const_defined?(s) ? Object.const_get(s).is_a?(Class) : false
end
  #=> ["A"]

请注意,这通常涉及类,而不仅仅是特定的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-08
    • 2018-04-13
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 2012-01-29
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多