Having just figured out this,我想知道-M
将如何处理附加到软件包名称的终端::
,
$ perl -MFoo:: -e1
我得到的是...
在
Foo/.pm
中找不到@INC
(您可能需要安装Foo::
模块)(@INC
包含:[...])。
这似乎表明它不起作用,所以好奇心迫使我....
$ 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
和调用之间添加一致性。此设计是出于意图吗?它记录在任何地方吗?以前有没有人想到过这个很棒的主意?
答案 0 :(得分:8)
使用惯例是否是mod ::;决定支持mod / .pm吗?
否。
在接受::
时,解析器过于宽松,让您做一些荒唐的事情。
$ 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
作为有意的,受支持的功能。
以前有没有人想到过这个很棒的主意?
那实际上是一团糟。
对于初学者,您将不得不使用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
方法,这种方法也可能会发生变化,并且具有两种不同且不兼容的加载模块约定很有害。
此行为来自何处
虽然表达式Foo::Bar::
生成字符串Foo::Bar
,但是use
不使用表达式。
此外,文字会传递到程序包名称到文件名音译的实现中,不执行完整性检查。 Perl仅执行等效于调用以下子项的操作:
sub pkg_to_qfn { ( $_[0] =~ s{::}{/}gr ) . '.pm' }
答案 1 :(得分:1)
此约定的一个次要缺点是,它打破了Renderer2.appendChild
在const arrayFullOfPromises = [];
arrayFullOfPromises.push(mongooseModelA.find({_id: aId}).exec());
arrayFullOfPromises.push(mongooseModelB.find({_id: bId}).exec());
Promise.all(arrayFullOfPromises).then(results => console.log(results));
中的先前假设。因此没有终端Foo/Bar.pm
的{{1}}语句不起作用,
Foo/Bar.pm
因此use
语法与已经起作用的::
代码兼容。更改模块的位置会破坏与较旧的mkdir Foo
mkdir Foo/Bar
echo "package Foo::Bar { sub baz { } } 1" > Foo/Bar/.pm
# Dies can't resolve to file,
PERL5LIB=. perl -MFoo::Bar -e1
Can't locate Foo/Bar.pm in @INC ...
# Works fine.
PERL5LIB=. perl -MFoo::Bar:: -e1
语句的兼容性(因此也必须对其进行更新)。