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

在这些Perl使用行中会发生什么?

  •  3
  • Geo  · 技术社区  · 16 年前

    我不明白这里发生了什么:

    use PAR { file => 'foo.par', fallback => 1 };
    

    我认为这是一个匿名散列。模块如何从 use 行?你能发光吗?

    编辑:我对par模块不感兴趣。我只是对窗帘背后的效果感兴趣。我怎样才能像那样配置我的模块?

    5 回复  |  直到 7 年前
        1
  •  7
  •   Ether    16 年前

    更基本的说,这就是有趣的hashref语法所做的(使用 perldoc -f use 作为参考):

    假设我们有这个基本模块 Foo.pm 在当前目录中):

    package Foo;
    
    use Data::Dumper;
    sub import
    {
        print "import was passed these arguments: ". Dumper(\@_);
    }
    
    1;
    

    当我们呼唤 perl -I. -wle'use Foo { a => 1, b => 2}' 代码 Foo->import({a=>1, b=>2}) 执行。这就是我们得到的输出:

    import was passed these arguments: $VAR1 = [
              'Foo',
              {
                'a' => 1,
                'b' => 2
              }
            ];
    

    基本上,这个语法让我们可以用 Exporter 但事实上你可以 import() 做任何你喜欢做的事(一定要大量记录,以免引起混乱!)

        2
  •  7
  •   FMc TLP    16 年前

    当你 use 一个模块,您可以向它传递参数列表。在您的示例中(似乎有错别字,缺少右引号),传递了一个包含一个元素(散列引用)的列表。

    更一般地说:

    use Module LIST
    

    变成这样:

    BEGIN {
        require Module;
        Module->import( LIST );
    }
    

    这个 BEGIN 块确保所有的事情都在编译时发生。这个 require 如果模块不在内存中,则将其加载到内存中。然后是模块的 import() 用传递的参数调用方法(作为 LIST )原版 使用 声明。

    为了让你自己的模块用这样一个 对于参数,您的模块需要定义 输入() 方法。许多模块不这样做;相反,它们继承 导入() Exporter 班级。见 perldoc -f use 了解更多详细信息。

    如果模块定义了自己的 导入() 方法,您将需要自己将符号导出到客户机代码中,或者更常见地,使用 export_to_level() 方法由提供 出口商 .此方法的第一个参数是一个正整数,指定要将符号导出到的调用堆栈中的级别。最常见的值1表示将符号导出一个级别 在上面 当前包——也就是使用模块的客户机代码。以下是您的 输入() 方法需要这样做。

    sub import {
        my ($class, @args) = @_;
    
        # Do whatever you need to do with the LIST of arguments
        # supplied by the client code using your module.
    
    
        # Let Exporter do its normal work of exporting symbols
        # into the client code using your module.
        $class->export_to_level(1, @_);
    }
    
        3
  •  2
  •   Michael Carman    16 年前

    是的,那是一个匿名哈希。它作为参数传递给模块 import 方法。

        4
  •  0
  •   Ether    16 年前

    par是CPAN模块 Perl Archive Toolkit . hashref是传递给par的配置参数。

    代码:

    use PAR { file => 'foo.par, fallback => 1 };
    use Foo::Bar;
    

    使用方法 Foo::Bar 如果它可用,但如果不可用,则返回到使用存档“ foo.par “(可能包含 酒吧:酒吧 )

        5
  •  0
  •   tsee    16 年前

    直接回答你的问题 this (line 340) :

    # called on "use PAR"
    sub import {
        my $class = shift;
        [...]
        my @args = @_;
        [...]
        # process args to use PAR 'foo.par', { opts }, ...;
        foreach my $par (@args) {
            if (ref($par) eq 'HASH') { # <---- This is what handle's your case!
                # we have been passed a hash reference
                _import_hash_ref($par);
            }
            elsif ($par =~ /[?*{}\[\]]/) {
               # implement globbing for PAR archives
               [...]
            }
            else {
                # ordinary string argument => file
                [...]
            }
        }
    

    现在,不幸的是,一旦你深入到实际发生的事情中,你会发现你已经选择了CPAN上最复杂的模块作为学习的例子,所以我建议你看看 fine documentation on modules instead . 为了给您提供一个要查找的指导:当您“使用”一个模块并为use语句提供参数时,Perl将加载该模块并用参数列表调用它的“import”方法。

    在您的示例中,只有一个参数:对哈希的引用。key=>“value”,key2=>“value2”,…语法是匿名哈希的构造函数。这些记录在 the perlref manual page ,但用更友好的术语解释 the perlreftut tutorial .

    推荐文章