如何确定对ruby的调用需要向全局命名空间添加哪些对象?

如何确定对ruby的调用需要向全局命名空间添加哪些对象?,ruby,Ruby,假设我有一个文件example.rb,如下所示: # example.rb class Example def foo 5 end end 我加载的require或require\u relative。如果我不知道定义了example.rb的example,是否有一个列表(除了ObjectSpace)可以检查以查找任何已定义的对象?我试过检查全局变量,但似乎不起作用 谢谢 这取决于“全局名称空间”的含义。Ruby实际上没有“全局”名称空间(除了全局变量)。它有一种“根”名称空间

假设我有一个文件
example.rb
,如下所示:

# example.rb
class Example
  def foo
    5
  end
end
我加载的
require
require\u relative
。如果我不知道定义了
example.rb
example
,是否有一个列表(除了
ObjectSpace
)可以检查以查找任何已定义的对象?我试过检查
全局变量
,但似乎不起作用


谢谢

这取决于“全局名称空间”的含义。Ruby实际上没有“全局”名称空间(除了全局变量)。它有一种“根”名称空间,即
对象
类。(尽管请注意,
对象
可能有一个超类,并混合在
内核
中,并且可以从中继承内容。)

“全局”常量只是
对象的常量。“全局函数”只是
对象的私有实例方法

因此,您可以通过在调用
require
/
require\u relative
之前和之后检查
全局变量
对象.常量
对象.实例方法
来合理接近

但是,请注意,根据您对
main
的“全局名称空间”(private)单例方法的定义,
main的单例方法也可以计算在内,因此您也可以检查这些方法

当然,脚本添加的任何方法在以后调用时都可以向全局范围添加其他内容。例如,以下脚本不向作用域添加任何内容,但调用该方法将:

class String
  module MyNonGlobalModule
    def self.my_non_global_method
      Object.const_set(:MY_GLOBAL_CONSTANT, 'Haha, gotcha!')
    end
  end
end

但是,严格地说,您要求将“对象”添加到全局名称空间中,常量、方法或变量都不是对象,所以OOOOOO…答案总是“无”?

尽管Ruby提供了很多反射方法,但它并没有真正为您提供一个顶级视图,可以识别发生了什么变化(如果有的话)。只有当你有一个特定的目标,你才能深入挖掘

例如:

def tree(root, seen = { })
  seen[root] = true

  root.constants.map do |name|
    root.const_get(name)
  end.reject do |object|
    seen[object] or !object.is_a?(Module)
  end.map do |object|
    seen[object] = true
    puts object

    [ object.to_s, tree(object, seen) ]
  end.to_h
end

p tree(Object)
现在,如果树结构中有任何变化,你就有了新的东西。使用
seen
作为触发器,可以为此编写一个diff方法


问题是,评估Ruby代码可能不一定会创建它将创建或可能创建的所有类。Ruby允许对任何和所有类进行广泛的修改,在运行时它通常会创建更多类,或者替换和删除其他类。只有强制声明所有模块和类的库才能使用这种技术,我认为这只是其中的一小部分。

不,没有。您将不得不使用ObjectSpace。(还有,全局变量和常量不是一回事。)如果你在寻找除“否”之外的另一个答案,也许可以通过构建为什么不想使用
ObjectSpace
来解决这个问题,这里有
Object.constants
,但这只会让你从根本上定义事物。