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

在使用Perl模块之前,如何检查它?

  •  46
  • dlamblin  · 技术社区  · 16 年前

    我有以下Perl代码,它依赖于 Term::ReadKey 要获取终端宽度,我的netbsd构建缺少此模块,因此我希望在模块丢失时将终端宽度默认为80。

    我不知道如何有条件地使用一个模块,提前知道它是否可用。我当前的实现只是放弃了一条消息,说它找不到 术语:RealKEY 如果缺席的话。

    #/usr/pkg/bin/perl -w
    # Try loading Term::ReadKey
    use Term::ReadKey;
    my ($wchar, $hchar, $wpixels, $hpixels) = GetTerminalSize();
    my @p=(2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97);
    my $plen=$#p+1;
    printf("num |".("%".int(($wchar-5)/$plen)."d") x $plen."\n",@p);
    

    我在netbsd上使用perl 5.8.7,在cygwin上使用perl 5.8.8 你能帮助我更有效地将它实现到我的脚本中吗?

    6 回复  |  直到 9 年前
        1
  •  86
  •   Hasturkun    9 年前

    下面是一个不需要其他模块的简单解决方案:

    my $rc = eval
    {
      require Term::ReadKey;
      Term::ReadKey->import();
      1;
    };
    
    if($rc)
    {
      # Term::ReadKey loaded and imported successfully
      ...
    }
    

    注意下面所有的答案(我希望它们都在这一个下面!-)使用 eval { use SomeModule } 是错误的,因为 use 语句在编译时进行计算,而不管它们出现在代码中的什么位置。所以如果 SomeModule 不可用,脚本将在编译后立即死亡。

    (字符串eval of a 使用 声明也有效( eval 'use SomeModule'; 但是在运行时分析和编译新代码没有意义 require / import pair执行相同的操作,并在编译时检查语法以引导。)

    最后,注意我的用法 eval { ... } $@ 下面是这个例子的目的。在真正的代码中,您应该使用 Try::Tiny ,或者至少 be aware of the issues it addresses .

        2
  •  11
  •   brian d foy    16 年前

    查看CPAN模块 Module::Load::Conditional . 它会做你想做的。

        3
  •  6
  •   Jonathan Leffler    16 年前

    经典的答案(至少可以追溯到Perl4,早在“使用”之前)是“require()”一个模块。这是在脚本运行时执行的,而不是在编译时执行的,您可以测试成功或失败,并做出适当的反应。

        4
  •  4
  •   Hinrik    16 年前

    如果您需要模块的特定版本:

    my $GOT_READKEY;
    BEGIN {
        eval {
            require Term::ReadKey;
            Term::ReadKey->import();
            $GOT_READKEY = 1 if $Term::ReadKey::VERSION >= 2.30;
        };
    }
    
    
    # elsewhere in the code
    if ($GOT_READKEY) {
        # ...
    }
    
        5
  •  4
  •   Jason Plank Maksim Kondratyuk    13 年前
    if  (eval {require Term::ReadKey;1;} ne 1) {
    # if module can't load
    } else {
    Term::ReadKey->import();
    }
    

    if  (eval {require Term::ReadKey;1;}) {
    #module loaded
    Term::ReadKey->import();
    }
    

    注: 1; 仅在以下情况下执行 require Term::... 正确装载。

        6
  •  0
  •   Utkarsh Kumar    10 年前

    我认为它在使用变量时不起作用。 请检查 this link 这就解释了它如何与变量一起使用

    $class = 'Foo::Bar';
            require $class;       # $class is not a bareword
        #or
            require "Foo::Bar";   # not a bareword because of the ""
    

    require函数将在@inc数组中查找“foo::bar”文件,并抱怨没有在其中找到“foo::bar”。在这种情况下,您可以执行以下操作:

     eval "require $class";