获取 Ruby 中任何给定模块的嵌套层次结构
Getting the nesting heirarchy for any given module in Ruby
我有一个方法需要能够访问模块定义的嵌套层次结构。假设我有这个定义:
module A
module B
module C
end
end
end
我正在尝试编写一个方法,如果将对 C
的引用传递给该方法,它能够 return Module.nesting
的结果,就好像它在定义中被调用。例如:
get_nesting(A::B::C) # => [A::B::C, A::B, A]
但是,我不知道如何在不同的上下文中调用 Module.nesting
。我试过使用 instance_exec
,但这只是 return 当前范围内的嵌套。
module X
def self.get_nesting(m)
m.instance_exec { Module.nesting }
end
end
X.get_nesting(A::B::C) # => [X]
我想要 return [A::B::C, A::B, A]
代替。
有没有办法以这种方式使用 Module.nesting
或其他方式获得模块的嵌套?
试试这个:
module A
module B
module C
Module.nesting
end
end
end
#=> [A::B::C, A::B, A]
module A::B
module C
Module.nesting
end
end
#=> [A::B::C, A::B]
A
未包含在最后一个 return 值中的原因是 nesting
取决于代码结构 ("lexical") 而不是 parent-child 模块的关系。出于这个原因,我认为任何导致 self
等于给定模块(方法的参数)然后执行 Module.nesting
的方法都注定要失败。
但是,您可以执行以下操作。
def get_nesting(mod)
a = mod.to_s.split('::')
a.size.times.map { |i| Module.const_get(a[0..i].join('::')) }.reverse
end
get_nesting(A) #=> [A]
get_nesting(A::B) #=> [A::B, A]
get_nesting(A::B::C) #=> [A::B::C, A::B, A]
get_nesting(A::B::C).map { |m| m.class }
#=> [Module, Module, Module]
考虑到这取决于 Module#to_s,这将被归类为拼凑。
我有一个方法需要能够访问模块定义的嵌套层次结构。假设我有这个定义:
module A
module B
module C
end
end
end
我正在尝试编写一个方法,如果将对 C
的引用传递给该方法,它能够 return Module.nesting
的结果,就好像它在定义中被调用。例如:
get_nesting(A::B::C) # => [A::B::C, A::B, A]
但是,我不知道如何在不同的上下文中调用 Module.nesting
。我试过使用 instance_exec
,但这只是 return 当前范围内的嵌套。
module X
def self.get_nesting(m)
m.instance_exec { Module.nesting }
end
end
X.get_nesting(A::B::C) # => [X]
我想要 return [A::B::C, A::B, A]
代替。
有没有办法以这种方式使用 Module.nesting
或其他方式获得模块的嵌套?
试试这个:
module A
module B
module C
Module.nesting
end
end
end
#=> [A::B::C, A::B, A]
module A::B
module C
Module.nesting
end
end
#=> [A::B::C, A::B]
A
未包含在最后一个 return 值中的原因是 nesting
取决于代码结构 ("lexical") 而不是 parent-child 模块的关系。出于这个原因,我认为任何导致 self
等于给定模块(方法的参数)然后执行 Module.nesting
的方法都注定要失败。
但是,您可以执行以下操作。
def get_nesting(mod)
a = mod.to_s.split('::')
a.size.times.map { |i| Module.const_get(a[0..i].join('::')) }.reverse
end
get_nesting(A) #=> [A]
get_nesting(A::B) #=> [A::B, A]
get_nesting(A::B::C) #=> [A::B::C, A::B, A]
get_nesting(A::B::C).map { |m| m.class }
#=> [Module, Module, Module]
考虑到这取决于 Module#to_s,这将被归类为拼凑。