如何在模块定义之外访问 Module.nesting 的返回

How to access the return of Module.nesting outside of the module definition

提问人:thekyle 提问时间:11/30/2019 最后编辑:the Tin Manthekyle 更新时间:11/30/2019 访问量:59

问:

使用 Module.nesting 方法时,我可以从调用点返回嵌套模块列表。我在文档和其他地方看到的唯一示例显示了在嵌套模块定义中放置和运行的方法调用:

module M1
  module M2
    Module.nesting #=> [M1::M2, M1]
  end
end

在以下示例中:

module A
  module B; end
  module C
    module D
      # I want to access the name-space chain from this point
    end
  end
end

# But how can I reference it from our here?
# A::C::D .... ?

有没有办法在定义模块后检查模块中的命名空间链?

我能看到的唯一示例在定义中创建一个变量,以保存要在定义外部再次引用的结果调用:

module A
  module B; end
  module C
    module D
      $chain = Module.nesting
    end
  end
end

p $chain 
#=> [A::C::D, A::C, A]

有没有一种方法可以查找此名称间距链,而无需在定义中创建变量以供稍后引用?

Ruby 方法 模块 命名空间 常量

评论

1赞 tadman 11/30/2019
这些信息在这种背景之外有什么用处?它与通过拆分模块名称得到的有何不同?::
1赞 thekyle 1/17/2020
老实说,这个问题纯粹是出于好奇。我不知道我是否想到了特定的用例。只是想知道这种事情是否可能!
0赞 tadman 1/17/2020
通过学术探究来促进理解并没有错。只是问,因为可能有另一种更简单的方法来解决您遇到的问题。

答:

0赞 Cary Swoveland 11/30/2019 #1

请考虑问题中提到的以下嵌套模块。

module A
  module B; end
  module C
    module D
      Module.nesting
    end
  end
end
  #=> [A::C::D, A::C, A] 

现在试试这个:

module A::C::D
  Module.nesting
end
  #=> [A::C::D]

Module::nesting 以字典方式解析模块的嵌套,这意味着模块按其包含点排序,从开始并向外工作。 不“记住”定义模块的嵌套;它只是在本地检查代码。这与子类化形成鲜明对比。A::C::DModule::nesting

也许您可以使用 ObjectSpace::each_method 方法获取所需的信息。

outer_module = A
ObjectSpace.each_object(Module).select { |m| m.to_s.match?(/\A#{outer_module}::/) }
  #=> [A::B, A::C::D, A::C]
1赞 Jörg W Mittag 11/30/2019 #2

在 Ruby 中,“记住”表达式值的方法是将该值分配给变量。

此外,模块定义的值是在正文中计算的最后一个表达式的值。

如果你把两者放在一起,你会得到这样的结果:

chain = module A
  module B; end
  module C
    module D
      Module.nesting
    end
  end
end

p chain 
# [A::C::D, A::C, A]