如何从 Perl 中的部分命名空间动态发现包?
我的目录结构如下所示:
Foo::Bar::Baz::1 Foo::Bar::Baz::2 等
我可以列出类似以下内容的包:
use Foo::Bar::Baz;
谢谢!
编辑:更清楚地说明了模块是什么。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想加载包含路径中具有特定前缀的所有模块(例如
a::b::c
下的所有模块,您可以使用 Module::Find。例如:
这取决于您使用以下命令设置的
@INC
路径必要的目录,因此首先进行任何所需的操作(例如使用use lib
)。If you want to load all modules in your include path with a certain prefix (e.g. everything under
a::b::c
, you can use Module::Find.For example:
This depends on your
@INC
path being set up with the necessary directories, so do any required manipulation (e.g. withuse lib
) first.通常,像 a/b/c.pl 这样的脚本不会有
main
之外的命名空间。也许您正在考虑使用诸如 a/b/c.pm 之类的名称来发现模块(这是一个不好的名称,因为小写的包名称通常是为 Perl 内部保留的)。但是,给定目录路径,您可以使用 潜在 Perl 模块>文件::查找:
Normally a script such as a/b/c.pl won't have a namespace other than
main
. Perhaps you are thinking of discovering modules with names such as a/b/c.pm (which is a bad name, since lower-cased package names are generally reserved for Perl internals).However, given a directory path, you can look for potential Perl modules using File::Find:
这可能有点过头了,但是您可以在加载模块之前和之后检查符号表并查看发生了什么变化:
This might be overkill, but you can inspect the symbol table before and after loading the module and see what changed:
需要明确的是,您是否正在查看随机 Perl 代码中的随机包?
或者对于 Perl 模块,例如“a/b/c/d1.pm”和模块“a::b::c::d1”?
无论哪种情况,您都不能使用单个“use”语句来加载所有它们。
您需要做的是使用
glob
或File::Find
查找所有适当的文件。在第一种情况(模块)中,您可以通过
require
-ing 每个文件来加载它们,或者通过将文件名转换为模块名称(s#/#::#g; s# \.pm$##;
) 并分别在每个模块上调用use
。至于嵌套在随机 Perl 文件中的实际包,这些包可以是:
通过 grep 每个文件列出(同样,通过
glob
或File::Find
找到) for/^package (.*);/
实际是通过对每个文件执行
require $file
来加载的。在这种情况下,请注意
a/b/c/1.pl
中每个包的包名称不需要与“ a::b::c" - 例如它们可以由文件作者“p1”、“a::p1”或“a::b::c::p1_something”命名。Just to be clear, are you looking at random packages in random Perl code?
Or for Perl modules, e.g. "a/b/c/d1.pm" with module "a::b::c::d1"?
In either case, you can not use a single "use" statement to load them all.
What you need to do is to find all the appropriate files, using either
glob
orFile::Find
.In the first case (modules), you can then load them either by
require
-ing each file, OR by converting filename into module name (s#/#::#g; s#\.pm$##;
) and callinguse
on each module individually.As far as actual packages nested in random Perl files, those packages can be:
Listed by grepping each file (again, found via
glob
orFile::Find
) for/^package (.*);/
Actually loaded by executing
require $file
for each file.In this case, please note that the package name for each of those packages in
a/b/c/1.pl
will NOT need to be related to "a::b::c" - e.g. they CAN be named by the file author "p1", "a::p1" or "a::b::c::p1_something".