gpt4 book ai didi

perl - 版本相关的回退代码

转载 作者:行者123 更新时间:2023-12-01 12:34:41 25 4
gpt4 key购买 nike

我有一个需要在多个服务器上运行的脚本,但是,每个服务器可能没有相同版本的 Perl 可用,并且可能具有不同的功能。

Perl v5.14 引入了 /r modifier for regular expressions它返回替换的结果并单独保留原始文本。如果那不可用,我想改用一些后备代码。

这是一个例子:

#!/usr/bin/perl

# Don't use cryptic variable names
use English;

my $str = "Hello, World!";
my $search = ',';

if ($PERL_VERSION ge v5.14) {
print "Using version that supports /r modifier\n";

# Perl v5.14 introduced the /r flag for regular expressions
# From the perldoc: r - perform non-destructive substitution and return the new value
print "After replacement: " . ($str =~ s/\Q${search}\E/_/gr) . $/;
print "Original string: " . $str . $/;

} else {
print "This version does not support the /r modifier\n";

# Prior to Perl v5.14, no /r option existed and the original string will be clobbered
# To deal with this, we need to make a copy first, then modify the copy instead
my $str_copy = $str;
$str_copy =~ s/\Q${search}\E/_/g;

print "After replacement: " . $str_copy . $/;
print "Original string: " . $str . $/;
}

当 Perl v5.14 可用时,运行脚本会得到我想要的结果:

$ ./version_dependent.pl
Using version that supports /r modifier
After replacement: Hello_ World!
Original string: Hello, World!

当使用低于 v5.14 的版本时,由于 r 出现语法错误:

$ ./version_dependent.pl
Bareword found where operator expected at ./version_dependent.pl line 15, near "s/\Q${search}\E/_/gr"
syntax error at ./version_dependent.pl line 15, near "s/\Q${search}\E/_/gr"
Execution of ./version_dependent.pl aborted due to compilation errors.

我想得到的是:

$ ./version_dependent.pl
This version does not support the /r modifier
After replacement: Hello_ World!
Original string: Hello, World!

有没有办法让脚本按预期运行?
如果这是一种类似 C 的语言,我会使用预处理器处理该问题,但我认为 Perl 不具备该功能。


编辑:以上代码只是一个例子
在实际应用中,出于性能原因,我使用了 5.14 中的一些功能。我可以在低于 5.14 的版本中手动重新创建功能,但性能会受到影响。

最佳答案

许多最新功能不向前兼容。如您所见,使用对于您正在运行的 perl 版本而言太新的功能,您将遇到编译时错误。使用 block-eval 无济于事,因为 block 的内容需要对当前的 perl 解释器有效。

您在检查当前 perl 版本和分支方面走在正确的轨道上。 $] variable是一种机制来做到这一点。检查 $Config{PERL_VERSION}(在您使用 Config 之后)是另一回事。

ThisSuitIsBlackNot 将您指向 if pragma,即

use if $] >= 5.014, 'Foo::New';  # take advantage of latest syntax,features
use if $] <= 5.014, 'Foo::Old'; # workarounds for missing features

根据当前 perl 的功能加载不同的模块。在运行时,条件 require 语句可以以相同的方式工作

if ($] >= 5.014) {
require Foo::New;
} else {
require Foo::Old;
}

最后, block eval 不是版本相关代码的可行技术,但字符串 eval 是。要点是:

BEGIN {  # BEGIN block so these subs get parsed at compile time
if ($] >= 5.014) {
eval q^*substwrepl = sub {
my ($str,$search) = @_;
$str =~ s/\Q${search}\E/_/gr
};^;
} else {
eval q^*substwrepl = sub {
my ($str,$search) = @_;
my $str_copy = $str;
$str_copy =~ s/\Q${search}\E/_/g;
$str_copy;
};^;
}
}

... # later in your program
my $str = "Hello, world";
print "After replacement: ", substrwrepl($str, ","), "\n";
print "Original string: ", $str, "\n";

See the Test::Builder module用于实际使用此结构。

关于perl - 版本相关的回退代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30851957/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com