【问题标题】:How do I include functions from another file in my Perl script?如何在我的 Perl 脚本中包含来自另一个文件的函数?
【发布时间】:2010-12-15 06:48:09
【问题描述】:

这似乎是一个非常简单的问题,但不知怎的,我的 Google-Fu 让我失望了。

在 Perl 中包含来自其他文件的函数的语法是什么?我正在寻找类似 C 的 #include "blah.h"

我看到了使用 Perl 模块的选项,但这似乎需要对我当前的代码进行重大的重写。

【问题讨论】:

  • 随意将脚本相互包含是自找苦吃。模块和脚本在代码上的区别很小,但封装要好得多。哪些具体的事情让您认为使用模块需要进行重大重写?
  • 我在网上查看的指南使创建和添加模块看起来比实际复杂得多。感谢您向我展示它的简单性

标签: perl include


【解决方案1】:

我相信您正在寻找 requireuse 关键字。

【讨论】:

    【解决方案2】:

    你真的应该研究一下 perl 模块,但是,为了快速破解,你总是可以运行“perl -P”,它通过 C 预处理器运行你的 perl 脚本。这意味着你可以做#include 和朋友....

    不过只是快速破解,请注意 ;-)

    【讨论】:

      【解决方案3】:

      Perl require 将完成这项工作。您需要通过添加

      来确保任何“必需”文件返回真实情况
      1;
      

      在文件末尾。

      这是一个小样本:

      $ cat m1.pl 
      use strict;
      sub x { warn "aard"; }
      1;
      
      $ cat m2.pl 
      use strict;
      require "m1.pl";
      x();
      
      $ perl m2.pl 
      aard at m1.pl line 2.
      

      但是尽快迁移到模块

      编辑

      将代码从脚本迁移到模块的一些好处:

      • 如果没有包,所有内容都占用一个命名空间,因此您可能会遇到来自不同文件的两个函数需要相同名称的情况。
      • 包允许您公开某些功能,但隐藏其他功能。没有包,所有功能都是可见的。
      • require 中包含的文件仅在运行时加载,而 use 中加载的包需要在早期的编译时检查。

      【讨论】:

      • 据我所知,这个更直接地与 C 的#include 相媲美,并且正是我所需要的。
      • A package allows you to expose some functions, but hide others. With no packages, all functions are visible. 我们如何做到这一点?
      【解决方案4】:

      使用模块。查看perldoc perlmodExporter

      在文件 Foo.pm 中

      package Foo;
      use strict;
      use warnings;
      use Exporter;
      
      our @ISA= qw( Exporter );
      
      # these CAN be exported.
      our @EXPORT_OK = qw( export_me export_me_too );
      
      # these are exported by default.
      our @EXPORT = qw( export_me );
      
      sub export_me {
          # stuff
      }
      
      sub export_me_too {
          # stuff
      }
      
      1;
      

      在你的主程序中:

      use strict;
      use warnings;
      
      use Foo;  # import default list of items.
      
      export_me( 1 );
      

      或者同时获得这两个功能:

      use strict;
      use warnings;
      
      use Foo qw( export_me export_me_too );  # import listed items
      
      export_me( 1 );
      export_me_too( 1 );
      

      您也可以导入包变量,但强烈建议不要这样做。

      【讨论】:

      • 查看 Sub::Exporter 它是所有的狂欢! search.cpan.org/~rjbs/Sub-Exporter-0.982/lib/Sub/Exporter.pm
      • 此外,如果您没有将模块安装在 perl 模块的默认位置之一,只需在“use Foo;”之前添加它行:使用 lib ('C:/Module/Location');
      • 假设我有来自默认位置的库,我想使用位于本地目录中的模块,因为它实际上仅由当前应用程序使用,并且创建模块是为了更好地组织脚本。 use lib 行会告诉 perl 只查看我为所有模块指定的位置还是添加到 perl 搜索的 lib 路径?
      • 是否可以在主脚本以及您创建的模块中使变量成为全局变量?如果是这样,当我遇到一些麻烦时,该怎么做?非常感谢
      【解决方案5】:

      你要找的是'require file.pl',但你应该看的是'use module'。

      【讨论】:

        【解决方案6】:

        另外,do 'file.pl'; 也可以,但模块是更好的解决方案。

        【讨论】:

          【解决方案7】:

          我知道这个问题特别提到了“函数”,但是当我寻找“perl include”时,我在搜索中得到了这篇文章,而且经常(比如现在)我想包含变量(以一种简单的方式,没有必须考虑模块)。所以我希望可以在这里发布我的示例(另请参阅:Perl require and variables;简而言之:使用require,并确保“includer”和“includee”文件都将变量声明为our):

          $ perl --version
          
          This is perl, v5.10.1 (*) built for i686-linux-gnu-thread-multi ...
          
          $ cat inc.pl
          use warnings;
          use strict;
          
          our $xxx = "Testing";
          
          1;
          
          $ cat testA.pl 
          use warnings;
          use strict;
          
          require "inc.pl";
          our $xxx;
          
          print "1-$xxx-\n";
          print "Done\n";
          
          $ perl testA.pl 
          1-Testing-
          Done
          
          
          $ cat testB.pl 
          use warnings;
          use strict;
          
          our $xxx;
          print "1-$xxx-\n";
          
          $xxx="Z";
          print "2-$xxx-\n";
          
          require "inc.pl";
          
          print "3-$xxx-\n";
          print "Done\n";
          
          $ perl testB.pl 
          Use of uninitialized value $xxx in concatenation (.) or string at testB.pl line 5.
          1--
          2-Z-
          3-Testing-
          Done
          

          【讨论】:

          • 正是我想要的。没有人建议这不是一个好主意?所以我认为这意味着它仍然是为多个 perl 脚本提供一组值的好方法?
          【解决方案8】:

          以上答案都忽略了客户端部分:如何导入模块。

          在此处查看接受的答案: How do I use a Perl module from a relative location?

          如果没有这个答案中的技巧,当您use $mymodule; 时,您将很难找到正确的模块路径

          【讨论】:

            【解决方案9】:

            require 大致相当于包含。所有命名空间的好处都可以在所需的 perl 脚本中实现,就像 perl 模块一样。 “魔法”就在你在脚本中的内容中。

            包含脚本的唯一注意事项是您需要在脚本末尾return 1;,否则即使您没有在脚本中调用任何内容,perl 也会说它失败。

            require "./trims.pl"

            然后在你的 perl 脚本中它可以很简单:

            #!/usr/bin/perl
            
            #use "trims.pl";
            
            
            sub ltrim { my $s = shift; $s =~ s/^\s+//;       return $s };
            sub rtrim { my $s = shift; $s =~ s/\s+$//;       return $s };
            sub  trim { my $s = shift; $s =~ s/^\s+|\s+$//g; return $s };
            return 1;
            

            此示例从输入字符串的左侧、右侧或两端删除空格。 $string = trim($string);

            #use "trims.pl" 的注释可以粘贴到您的 perl 脚本中,取消注释(删除 #),perl 将在您的脚本所在的同一文件夹中查找 trims.pl,这会将函数 ltrim()、rtrim () 和 trim() 在全局名称空间中,因此您不能在任何其他全局名称空间中拥有这些函数名称,否则 perl 将检测到冲突并停止执行。

            要了解有关控制名称空间的更多信息,请查看“perl 包和模块”package Foo;

            https://perldoc.perl.org/functions/package

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-08-01
              • 2011-10-09
              • 2020-12-24
              相关资源
              最近更新 更多