perl - directory/.pm 曾经是一个约定吗?它为什么存在?

标签 perl import module require

Having just figured out this ,我想知道 -M将处理终端 ::附在包名上,

$ perl -MFoo:: -e1

我得到的是...

Can't locate Foo/.pm in @INC (you may need to install the Foo:: 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/

    相关文章:

    python - 包 "within"模块

    string - Perl - 如果字符串包含文本?

    perl - 当 "Can' t 通过包 y 定位对象方法 x 时打印堆栈跟踪"(Perl)

    import - Neo4j 服务器未在 120 秒内启动

    php - 使用 php 将内容从谷歌电子表格导入 MySql

    perl - 使用 perlbrew 时如何安装 CPAN 模块?

    perl - 如何将 CPAN 的配置从 local::lib 更改为 sudo 首选项

    perl - 如何使用 Apache2::Upload 处理表单提交中的多个文件?

    python - 在python3中运行时从动态路径导入固定模块

    javascript - Nodejs,最好有很多相同的要求或使用句柄?