【问题标题】:Including perl modules包括 perl 模块
【发布时间】:2011-05-09 16:29:17
【问题描述】:

我想知道,我在 perl 脚本中使用的所有模块都需要位于 a 脚本的开头吗?

我想知道的原因是我的脚本中有一个位置,它“拆分”的一种方式是脚本使用授权密钥与 SSH 连接。另一种方式是脚本使用用户名和密码与 SSH 连接。我正在使用模块 Net::OpenSSH 进行 SSH。根据 cpan 文档,如果我想要所有用户名和密码身份验证,我需要 IO::Pty。

如果触发了设置为使用用户名和密码登录的子例程,我只想检查IO::Pty 的要求。那可能吗?仅在触发某个子程序时才加载模块?

【问题讨论】:

    标签: perl


    【解决方案1】:

    use IO::Pty; 行对 Perl 的含义如下:

    BEGIN {
        require IO::Pty;
        IO::Pty->import;
    }
    

    所以首先 Perl 用 require 加载模块(如果找不到模块,它会死掉),然后如果它存在,它会调用 ->import 方法。

    您可以将其转换为运行时条件,如下所示:

     if (eval {require IO::Pty}) {
         # IO::Pty->import;
         # or use fully qualified names: IO::Pty::some_sub(...);
         # in both cases, the parenthesis after the subroutine are required, since
         # the import is not visible at compile time
     } else {
         # run other code, or throw an error with `die`
     }
    

    包导入其他包,而不是其他范围,因此导入将在执行它的子例程之外可见。最好一起跳过导入,只使用完全限定的名称。

    【讨论】:

    • 除非您在BEGIN 时间导入,否则编译器将没有正确的原型,实际上也不会让您将这些函数用作列表操作。运行时导入的用处要有限得多。
    • @tchrist - listop 到底是什么?谷歌似乎在这个词上毫无帮助。我猜你的意思是一个允许类似 sort/map 语法的函数?谢谢
    • @DVK:不,我的意思是不需要括号(无论如何我总是使用它)。
    • @tchrist - 啊。我正在考虑问一个关于省略括号是否有任何意义/好处的问题
    【解决方案2】:

    如果您只想加载一个模块有时,那么您可以使用 require 和 eval 来检查您是否拥有它:

    $haveit = eval "require Foo::Bar";
    if ($haveit) {
       # do something
    }
    

    “使用”例程实际上做了两件事:

    require Foo::Bar;
    import Foo::Bar;
    

    问题是“使用”在执行开始时执行此操作,而不是在有条件的地方。因此,如果您只想“有时”加载模块,请不要使用“使用”,而是在实际需要的地方使用 require 和 import。

    *编辑包括:*

    我应该参考 perl 'use' documentation 很好地解释了这一点。

    use Module;
    

    相当于:

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

    而且是“BEGIN”部分导致它被加载,无论它在脚本中的什么位置,即使在另一个 if() 子句中也是如此。

    【讨论】:

    • 啊,我明白了,但是如果我在子例程中执行import Foo::Bar,它只适用于子例程还是适用于整个脚本?
    • @Solignis,它导入到当前包中。
    • ikegami 是对的:主脚本的正常当前包是'main'。
    • 我明白了,这几乎可以回答我的问题。谢谢大家。
    • 请记住,运行时require 后跟import 与编译时use 不同,因为编译器经常被import 欺骗,并且确实事情不同,无论是因为看到的原型还是某些类型的重载。例如,这在 pragma 中尤其常见。
    【解决方案3】:

    还可以查看Module::Load。

    【讨论】:

      【解决方案4】:

      你不需要自己加载IO::Pty,Net::OpenSSH会在需要的时候加载。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-25
        • 1970-01-01
        • 2021-05-26
        • 2014-10-06
        • 1970-01-01
        • 1970-01-01
        • 2011-02-18
        相关资源
        最近更新 更多