【问题标题】:In Perl, how do I put multiple packages in a single .pm file?在 Perl 中,如何将多个包放在一个 .pm 文件中?
【发布时间】:2010-12-17 11:02:57
【问题描述】:

我很确定我在某个地方读到过它是可能的,但是您需要注意一些问题。不幸的是,我找不到描述您需要做什么的教程或页面。我浏览了Perl tutorials,并没有找到我记得读过的那个。有人能给我指出一个描述如何将多个包放入单个 .pm 文件的页面或文档吗?

【问题讨论】:

    标签: perl oop perl-module


    【解决方案1】:

    这是我通常的做法:

    use strict;
    use warnings;
    use 5.010;
    
    {
        package A;
        sub new   { my $class = shift; bless \$class => $class }
        sub hello { say 'hello from A' }
    }
    
    {
        package B;
        use Data::Dumper;
        sub new   { my $class = shift; bless { @_ } => $class }
        sub hello { say 'Hello from B + ' . shift->dump       }
        sub dump  { Dumper $_[0] }
    }
    
    $_->hello for A->new, B->new( foo => 'bar' );
    

    【讨论】:

    • 如果包已经定义了自己的范围,那么块范围有什么好处?
    • @ceving - 与 package 在 perl 5.14 中更改为现在允许以下语法的原因相同:package A { ... }。注意。这与{ package A; ... } 相同)。这避免了您可能会遇到myour 之类的陷阱。参考:perldoc.perl.org/5.14.0/functions/package.html
    • 导出、导入和继承呢?
    【解决方案2】:

    您只需使用另一个包语句开始新包:

    package PackageOne;
    
    # ...... code
    
    package PackageTwo;
    
    # .... more code
    

    Problems with this approach (archived on 2009)

    【讨论】:

    • 我很确定在我阅读的文章中,您还必须做一些其他事情,或者范围界定可能会出现问题。
    • 当然会有范围问题,这就是不推荐的原因,请参阅我添加的链接。
    • 您只能use 一个名称与文件名对应的包,并且您只能(轻松地)use 一个包含与其名称对应的包的文件。除此之外,文件范围的词法将“泄漏”到下一个包中(可以通过添加大括号来避免)这一事实没有太多要知道的。
    • 问题链接失效
    • 您可以通过“档案”访问该链接:web.archive.org/web/20090417065554/http://oreilly.com/catalog/…
    【解决方案3】:

    这对我有用:

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    
    {
       package A;
       use Exporter;
       our @ISA = qw(Exporter);
       our @EXPORT_OK = qw(a_sub);
       our @EXPORT = qw(a_sub);
    
       sub a_sub {
           # your code ...
       }
    }
    {
       package B;
       use Exporter;
       our @ISA = qw(Exporter);
       our @EXPORT_OK = qw(b_sub);
       our @EXPORT = qw(b_sub);
    
       sub b_sub {
           # your code ...
       }
    }
    
    # Main code starts here ##############
    
    use boolean;
    use Data::Dumper;
    
    import A qw(a_sub);
    import B qw(b_sub);
    
    a_sub();
    b_sub();
    

    重要的一点是,不要使用“use”,而是将其更改为“import”(这样它就不会去尝试查找文件)。

    【讨论】:

    • 我的做法也差不多,只是把{ package A; ... }改成了package A { ... }
    • 关于use 的观点非常好。 require 也是如此。如果需要userequire封装A,在userequire之前设置$INC{'A.pm'}=1。这告诉 perl 模块已经加载,不需要在磁盘上查看。对于use,该分配需要在BEGIN 块中,例如BEGIN { $INC{'A.pm'}=1; }
    • 这样可以导入常量(use constant)吗? use strict 我看到的是Can't use bareword ...
    【解决方案4】:

    怎么做:只需发出多个package 指令。

    我能想到的问题:my-variables 不是包本地化的,所以无论如何它们都是共享的。在你发布之前,默认情况下你在包main中。

    【讨论】:

    • 只使用package关键字时,不能使用use package
    • 你不能拥有一切,对吗? :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多