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

如何从Perl中的模块导出名为“import”的函数?

  •  4
  • Mithaldu  · 技术社区  · 15 年前

    我已经编写了一个特殊的导入函数,它将在一些地方使用,我希望能够在这些模块中“使用importrenamer”;并让它们今后使用从importrenamer获得的导入。我该怎么办?

    编辑:换句话说:我如何导入“import”而不运行它?

    4 回复  |  直到 15 年前
        1
  •  3
  •   DVK    15 年前

    更新

    既然OP澄清了他的需求,那么这确实应该以类似于导出操作的方式完成,更确切地说,通过glob分配将子引用注入调用者的名称空间。例子:

    ###############################################
    
    package ImportRenamer; 
    use strict;
    sub import_me {
       print "I am a cool importer\n";
    }
    
    sub import { 
      my ($callpkg)=caller(0);
      print "Setting ${callpkg}::import to ImportRenamer::import_me\n"; 
      no strict "refs";
      *{$callpkg."::import"} = \&ImportRenamer::import_me; # Work happens here!!!
      use strict "refs";
    }
    1;
    
    ###############################################
    
    package My; 
    use strict;
    use ImportRenamer; 
    1;
    
    ###############################################
    
    package My2; 
    use strict;
    use ImportRenamer; 
    1;
    
    ###############################################
    

    测试:

    > perl -e '{  package main; use My; use My2; 1;}'
    Setting My::import to ImportRenamer::import_me
    I am a cool importer
    Setting My2::import to ImportRenamer::import_me
    I am a cool importer
    

    原始答案

    除了调用import方法外,您不需要做任何特殊的事情。” import “。 use 已经呼叫 import() perldoc use :

    use Module LIST 
    

    将一些语义从命名模块导入到当前包中, 通常通过将某些子例程或变量名别名到包中。

    它完全等同于:

     BEGIN { require Module; Module->import( LIST ); }
    
        2
  •  3
  •   daotoad    15 年前

    你需要写一个自定义 import 模块中用于导出要在调用命名空间中调用的函数的方法import。

    以下是一些未测试的代码:

    package ImportMe;
    
    sub import { 
    
        # Get package name
        my $caller = caller;
    
        # Install my_import into the calling package as import
        {    no strict 'refs';
             *{"${caller}::import"} = \&my_import;
        }
    
        return 1;
    }
    
    # renamed as import when installing
    sub my_import {
    
       # do stuff
    
    }
    

    现在你可以把 use ImportMe; 在所有模块中 进口 将安装方法。

        3
  •  3
  •   Brian Phillips    15 年前

    作为替代方案,您可以使用 Sub::Exporter

    package Your::Module;
    
    use Sub::Exporter (
        -setup => {
            exports => {
                import => sub { return \&_real_import }
            },
            # the "default" group auto-exports "import" without the caller 
            # specifically asking for it
            groups => { default => [qw(import)] },
        }
    );
    
    sub _real_import { ... }
    

    编辑: 添加了自动导出的“默认”组

        4
  •  2
  •   friedo    15 年前

    像这样的怎么样:

    package Your::Module;
    
    use strict;
    use warnings;
    
    sub import { 
        # gets called by use Your::Module
        my ( $pkg ) = caller;
    
        no strict 'refs';
        *{ $pkg . '::import' } = \&_real_import;
    }
    
    sub _real_import { 
        # import function to be exported to caller
        print "blah blah";
    }
    

    这将手动分配 _real_import 子到 import 调用包命名空间的槽。如果你在一个 BEGIN 块,然后 进口 SUB应准备好并等待 那个 包获得 use d.