Having just figured out this ,我想知道 -M
将处理终端 ::
附在包名上,
$ perl -MFoo:: -e1
我得到的是...
Can't locate
Foo/.pm
in@INC
(you may need to install theFoo::
module) (@INC
contains: [...]).
这似乎表明它不起作用,所以好奇心迫使我......
$ mkdir Foo;
$ echo "package Foo { sub k { die 42 } }; 1;" > Foo/.pm
$ PERL5LIB=. perl -MFoo:: -e'Foo::->k'
这确实奏效了。这是
use mod::;
的约定吗?解析为 mod/.pm
支持的?这是从古代遗留下来的。这种行为是从哪里来的?有了这个模式,我可以做到,
Foo/.pm # package Foo
Foo/Bar/.pm # package Foo::Bar
Foo/Bar/Baz/.pm # package Foo::Bar::Baz;
那我可以做
use Foo::; # resolves to Foo/.pm
use Foo::Bar::; # resolves to Foo/Bar/.pm
use Foo::Bar::Baz::; # resolves to Foo/Bar/Baz/.pm
Foo::->new;
Foo::Bar::->new;
Foo::Bar::Baz::->new;
我喜欢这个,因为这增加了
use
之间的一致性和调用。 这个设计是有意的吗?它在任何地方都有记录吗?以前有没有人想过这个很棒的主意?
最佳答案
Is this convention of use mod::; resolving to mod/.pm supported?
不。
解析器在接受
::
时过于自由。 ,让你做一些比较荒谬的事情。$ cat Foo/Bar.pm
package Foo::Bar;
sub import { print "imported.\n"; }
print "loaded.\n";
1
$ perl -I. -e'require Foo::Bar'
loaded.
$ perl -I. -e'require Foo::::::Bar'
loaded.
使用非规范形式会导致问题。
$ perl -I. -e'use Foo::Bar; use Foo::Bar; use Foo::Bar;'
loaded.
imported.
imported.
imported.
$ perl -I. -e'use Foo::::::Bar; use Foo::::::Bar; use Foo::Bar;'
loaded.
loaded.
imported.
同样,
use Foo::Bar::
加载 Foo/Bar/.pm
不应将其视为有意的、受支持的功能。Has anyone ever thought of this awesome idea before?
实际上会是一团糟。
对于初学者,您必须使用
use Foo::Bar::;
而不是 use Foo::Bar;
.$ cat Foo/Bar/.pm
package Foo::Bar;
sub import { print "imported.\n"; }
sub baz { print "ok.\n"; }
1
$ perl -I. -e'use Foo::Bar;'
Can't locate Foo/Bar.pm in @INC ...
$ perl -I. -e'use Foo::Bar::;'
$
但是使用
use Foo::Bar::;
还不够,因为 import
从未被调用。 package 指令需要匹配 package Foo::Bar::
的文件名 ( import
)被调用,这意味着您还必须调整对包的合格引用。$ cat Foo/Bar/.pm
package Foo::Bar::;
sub import { print "imported.\n"; }
sub baz { print "ok.\n"; }
1
$ perl -I. -e'use strict; use Foo::Bar; Foo::Bar::baz();'
Can't locate Foo/Bar.pm in @INC ...
BEGIN failed--compilation aborted at -e line 1.
$ perl -I. -e'use strict; use Foo::Bar::; Foo::Bar::baz();'
imported.
Undefined subroutine &Foo::Bar::baz called at -e line 1.
$ perl -I. -e'use strict; use Foo::Bar::; Foo::Bar::::baz();'
imported.
ok.
说白了,这是不可取的。
即使您的模块没有
import
此时的方法可能会改变,并且有两种不同且不兼容的加载模块约定是有害的。Where did this behavior come from
而表达式
Foo::Bar::
产生字符串 Foo::Bar
, use
不带表情。此外,文字被传递给包名到文件名音译的实现,它不执行完整性检查。 Perl 简单地执行一个相当于调用以下 sub 的操作:
sub pkg_to_qfn { ( $_[0] =~ s{::}{/}gr ) . '.pm' }
关于perl - directory/.pm 曾经是一个约定吗?它为什么存在?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59107652/