代码之家  ›  专栏  ›  技术社区  ›  cowgod

在Perl中,有没有一种方法可以“使用”一个文件,而该文件又使用多个其他文件?

  •  9
  • cowgod  · 技术社区  · 17 年前

    使用 d在我的每个脚本中,如下所示:

    #!/usr/bin/perl
    
    use Foo::Bar;
    use Foo::Baz;
    use Foo::Qux;
    use Foo::Quux;
    
    # Potentially many more.
    

    使用 新模块的语句 Foo::Corge 然后只需要 use Foo::Corge 在我的每个脚本和模块中?

    6 回复  |  直到 17 年前
        1
  •  7
  •   jrockway    17 年前

    像这样的方法应该会奏效:

    http://mail.pm.org/pipermail/chicago-talk/2008-March/004829.html

    基本上,创建包含大量模块的软件包:

    package Lots::Of::Modules;
    use strict; # strictly optional, really
    
    # These are the modules we want everywhere we say "use Lots::Of::Modules".
    # Any exports are re-imported to the module that says "use Lots::Of::Modules"
    use Carp qw/confess cluck/;
    use Path::Class qw/file dir/;
    ...
    
    sub import {
        my $caller = caller;
        my $class  = shift;
    
        no strict;
        *{ $caller. '::'. $_ } = \*{ $class. '::'. $_ }
           for grep { !/(?:BEGIN|import)/ } keys %{ $class. '::' };
    }
    

    use Lots::Of::Modules;
    confess 'OH NOES';
    
        2
  •  7
  •   innaM    17 年前

    是的,这是可能的,但不,你不应该这样做。

    我刚刚花了两周的时间摆脱了一个只使用其他模块的模块。我猜这个模块一开始是简单和无辜的。但多年来,它成长为一个巨大的野兽,有着许许多多的使用声明,其中大部分都是我们的网络应用程序运行所不需要的。最后,仅仅“使用”这个模块就花了大约20秒。它支持延迟复制和粘贴模块创建。

    所以再说一遍:你可能会在几个月或几年后后悔这一步。你有什么好处?您在几个模块中节省了键入几行代码。了不起的事

        3
  •  3
  •   Community Mohan Dere    6 年前

    对

    在Foo/Corge.pm

    use Foo::Bar;
    use Foo::Baz;
    use Foo::Qux;
    use Foo::Quux;
    
    1;   # Be successful
    

    剩下的就是获取包含子目录的目录 Foo 添加到您的库路径( @INC ).或者,创建 Foo.pm 让它使用其他模块。他们会在一个 福 旁边的子目录 下午五时

    仔细想想,所有使用其他模块的复杂Perl模块都会一直这样做。它们不一定在同一个顶级包中( 福 在本例中),但使用它们也是必要的。

    虽然您可以使用Carp、Path::Class和招认等等(正如jrockway所建议的),但从我现在的位置来看,这似乎有些过分了。

        4
  •  0
  •   j_random_hacker    17 年前

    use Lots::Of::Modules; 有一个微妙的缺陷——见下图。这一修正方案让事情变得更加丑陋,但仍然可行。]

    BEGIN { ... } 确保定义的任何函数在编译时可用。感谢jrockway指出这一点。]

    以下代码与jrockway的代码完全相同,只是更简单、更清晰:

    在Lots/Of/Modules.inc中:

    use Carp qw/confess cluck/;
    use Path::Class qw/file dir/;
    
    0;   # Flag an error if called with "use" or "require" instead of "do"
    

    要导入这4个功能:

    BEGIN { defined( do 'Lots/Of/Modules.inc' ) or die; }
    

    因为我们没有 package Lots::Of::Modules; 此文件开头的语句 use 语句将导出到调用方的包中。

    我们必须使用 do 而不是 使用 require ,因为后者只会加载文件一次(如果 使用Lots::Of::模块; 多次调用,例如在单独的模块中调用 使用 d)主程序)。更原始 做 @INC ,因此需要使用 defined .

        5
  •  0
  •   Dave Sherohman    17 年前

    package Foo::Corge;
    
    use base 'Exporter';
    BEGIN {
      our @EXPORT_OK = qw( bar baz qux quux );
    
      use Foo::Bar qw( bar );
      use Foo::Baz qw( baz );
      use Foo::Qux qw( qux );
      use Foo::Quux qw( quux );
    }
    1;
    

    (use语句可能超出了 BEGIN ,但这就是我检查代码的地方,以验证它是否按我认为的方式工作。实际上,这是一个密码 eval 是什么 use s、 所以他们有理由呆在里面 这可能不适用于您的情况。)

        6
  •  0
  •   Sérgio    12 年前

    使用@EXPORT代替@EXPORT\u OK更简单

    图书馆是:

    package mycommon;
    
    use strict;
    use warnings;
    
    use base 'Exporter';
    
    our @EXPORT = qw(test);
    
    sub test {
        print "this is a test";
    }
    
    1;
    

    #!/usr/bin/perl
    use strict;
    use warnings;
    use mycommon;
    
    common::test()