I have the following Perl code which relies on Term::ReadKey
to get the terminal width; My NetBSD build is missing this module, so I want to default the width of the terminal to 80 when the module is missing.
我有以下Perl代码,它依赖于Term :: ReadKey来获取终端宽度;我的NetBSD版本缺少此模块,因此我希望在模块丢失时将终端的宽度默认为80。
I can't figure out how to conditionally use a module, knowing ahead of time whether it is available. My current implementation just quits with a message saying it can't find Term::ReadKey
if it's absent.
我无法弄清楚如何有条件地使用模块,提前知道它是否可用。我当前的实现只是退出一条消息,说如果它不存在就找不到Term :: ReadKey。
#/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);
I'm using Perl 5.8.7 on NetBSD and 5.8.8 on CygWin Can you help me implement this into my script more effectively?
我在NetBSD上使用Perl 5.8.7,在CygWin上使用5.8.8你能帮我更有效地将它实现到我的脚本中吗?
6 个解决方案
#1
81
Here's a bare-bones solution that does not require another module:
这是一个不需要其他模块的简单解决方案:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Note that all the answers below (I hope they're below this one! :-) that use eval { use SomeModule }
are wrong because use
statements are evaluated at compile time, regardless of where in the code they appear. So if SomeModule
is not available, the script will die immediately upon compiling.
请注意,下面的所有答案(我希望它们低于这一个!:-)使用eval {use SomeModule}是错误的,因为use语句在编译时被评估,无论它们出现在代码中的哪个位置。因此,如果SomeModule不可用,脚本将在编译时立即死亡。
(A string eval of a use
statement will also work (eval 'use SomeModule';
), but there's no sense parsing and compiling new code at runtime when the require
/import
pair does the same thing, and is syntax-checked at compile time to boot.)
(use语句的字符串eval也可以工作(eval'使用SomeModule';),但是当require / import对执行相同的操作时,在运行时解析和编译新代码是没有意义的,并且在编译时进行语法检查开机。)
Finally, note that my use of eval { ... }
and $@
here is succinct for the purpose of this example. In real code, you should use something like Try::Tiny, or at least be aware of the issues it addresses.
最后,请注意我在这个例子中使用eval {...}和$ @是简洁的。在实际代码中,您应该使用类似Try :: Tiny的东西,或至少知道它解决的问题。
#2
10
Check out the CPAN module Module::Load::Conditional. It will do what you want.
查看CPAN模块Module :: Load :: Conditional。它会做你想要的。
#3
6
The classic answer (dating back to Perl 4, at least, long before there was a 'use') was to 'require()' a module. This is executed as the script is run, rather than when compiled, and you can test for success or failure and react appropriately.
经典的答案(可以追溯到Perl 4,至少在有'使用'之前很久)就是'require()'一个模块。这是在脚本运行时执行的,而不是在编译时执行,您可以测试成功或失败并做出适当的反应。
#4
4
And if you require a specific version of the module:
如果您需要特定版本的模块:
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
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
or
要么
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Note: the 1;
only executes if require Term::...
loaded properly.
注意:1;仅在需要正确加载Term :: ...时执行。
#6
0
I think it doesn't work when using variables. Please check this link which explains how it can be used with variable
我认为使用变量时它不起作用。请查看此链接,该链接说明了如何将其与变量一起使用
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
The require function will look for the "Foo::Bar" file in the @INC array and will complain about not finding "Foo::Bar" there. In this case you can do:
require函数将在@INC数组中查找“Foo :: Bar”文件,并抱怨在那里找不到“Foo :: Bar”。在这种情况下,你可以这样做:
eval "require $class";
#1
81
Here's a bare-bones solution that does not require another module:
这是一个不需要其他模块的简单解决方案:
my $rc = eval
{
require Term::ReadKey;
Term::ReadKey->import();
1;
};
if($rc)
{
# Term::ReadKey loaded and imported successfully
...
}
Note that all the answers below (I hope they're below this one! :-) that use eval { use SomeModule }
are wrong because use
statements are evaluated at compile time, regardless of where in the code they appear. So if SomeModule
is not available, the script will die immediately upon compiling.
请注意,下面的所有答案(我希望它们低于这一个!:-)使用eval {use SomeModule}是错误的,因为use语句在编译时被评估,无论它们出现在代码中的哪个位置。因此,如果SomeModule不可用,脚本将在编译时立即死亡。
(A string eval of a use
statement will also work (eval 'use SomeModule';
), but there's no sense parsing and compiling new code at runtime when the require
/import
pair does the same thing, and is syntax-checked at compile time to boot.)
(use语句的字符串eval也可以工作(eval'使用SomeModule';),但是当require / import对执行相同的操作时,在运行时解析和编译新代码是没有意义的,并且在编译时进行语法检查开机。)
Finally, note that my use of eval { ... }
and $@
here is succinct for the purpose of this example. In real code, you should use something like Try::Tiny, or at least be aware of the issues it addresses.
最后,请注意我在这个例子中使用eval {...}和$ @是简洁的。在实际代码中,您应该使用类似Try :: Tiny的东西,或至少知道它解决的问题。
#2
10
Check out the CPAN module Module::Load::Conditional. It will do what you want.
查看CPAN模块Module :: Load :: Conditional。它会做你想要的。
#3
6
The classic answer (dating back to Perl 4, at least, long before there was a 'use') was to 'require()' a module. This is executed as the script is run, rather than when compiled, and you can test for success or failure and react appropriately.
经典的答案(可以追溯到Perl 4,至少在有'使用'之前很久)就是'require()'一个模块。这是在脚本运行时执行的,而不是在编译时执行,您可以测试成功或失败并做出适当的反应。
#4
4
And if you require a specific version of the module:
如果您需要特定版本的模块:
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
if (eval {require Term::ReadKey;1;} ne 1) {
# if module can't load
} else {
Term::ReadKey->import();
}
or
要么
if (eval {require Term::ReadKey;1;}) {
#module loaded
Term::ReadKey->import();
}
Note: the 1;
only executes if require Term::...
loaded properly.
注意:1;仅在需要正确加载Term :: ...时执行。
#6
0
I think it doesn't work when using variables. Please check this link which explains how it can be used with variable
我认为使用变量时它不起作用。请查看此链接,该链接说明了如何将其与变量一起使用
$class = 'Foo::Bar';
require $class; # $class is not a bareword
#or
require "Foo::Bar"; # not a bareword because of the ""
The require function will look for the "Foo::Bar" file in the @INC array and will complain about not finding "Foo::Bar" there. In this case you can do:
require函数将在@INC数组中查找“Foo :: Bar”文件,并抱怨在那里找不到“Foo :: Bar”。在这种情况下,你可以这样做:
eval "require $class";