安装Perl模块时不能使用数组作为引用

x6yk4ghg  于 2022-11-15  发布在  Perl
关注(0)|答案(1)|浏览(145)

编辑:使用sudo cpanm Data::Match --force
我正在尝试用ubuntu 18.04安装“Data::Match”Perl模块。我用途:

perl Makefile.pl
make
make test

我得到以下错误:

make test
PERL_DL_NONLAZY=1 "/usr/bin/perl" "-Iblib/lib" "-Iblib/arch" test.pl
1..1
# Running under perl version 5.026001 for linux
# Current time local: Wed Jun 29 18:41:13 2022
# Current time GMT:   Wed Jun 29 15:41:13 2022
# Using Test.pm version 1.30
Can't use an array as a reference at blib/lib/Data/Match.pm line 968.
Compilation failed in require at test.pl line 10.
BEGIN failed--compilation aborted at test.pl line 10.
Makefile:825: recipe for target 'test_dynamic' failed
make: *** [test_dynamic] Error 255

我安装了许多其他模块,它们都工作得非常好。我还尝试用

perl -MCPAN -e shell

但这并没有帮助。
我该怎么办?

eh57zj3b

eh57zj3b1#

Data::Match模块有一些Perl v5.22收紧的语法,这就是它失败的原因。注意,强制安装一个有这样严重问题的模块意味着当你运行程序时它会失败。
如果可以的话,不要使用这个模块。我不知道它是做什么的,所以我没有任何替代的建议。
假设您出于某种原因需要这个模块,即使它已经有20年的历史了。
下面这行代码(L968)取消引用了一个数组元素,而该元素本身就是一个数组引用:

$str .= $sep . '{' . join(',', @$ind->[0]) . '}';

这应该是用于分隔引用部分的后缀表示法:

$str .= $sep . '{' . join(',', @{$ind->[0]}) . '}';

如果您在运行perl Makefile.PL之前对 * Match.pm * 进行了更改,则测试将通过(但会出现警告),您可以安装该模块。
如果这就是你所需要的,你可以停在这里。

分配优先级

CPAN.pm 有一种方法来处理这些情况,这样你就不必每次安装模块时都进行修改。在CPAN.pm开始工作之前,它可以修补有问题的发行版,建议替换发行版,或者做很多其他事情。你可以用“distroprefs”来做这些。在CPAN.pm repo中有很多例子。
有几件事要设置。首先,设置你的distroprefs目录(o conf init prefs_dir)。其次,配置一个目录来保存你的补丁(o conf patches_dir)。我选择了我的 .cpan 目录下的 patches,但它可以是任何东西。在退出之前保存你的更改。

% cpan
% cpan[1]> o conf init prefs_dir
Directory where to store default options/environment/dialogs for
building modules that need some customization? [/Users/brian/.cpan/prefs]
% cpan[2]> o conf patches_dir /Users/brian/.cpan/patches
% cpan[3]> o conf commit

distroprefs有两个部分。第一部分指定你想要发生什么。这可以是YAML、Storable或Data::Dumper文件。如果是YAML(大多数人似乎都用它),那么你需要先安装YAML模块。
下面是一个简单的distroprefs文件,它告诉CPAN.pm如何匹配CPAN上的发行版(AUTHOR/FILE)。在这个例子中,它的action是patches,这是一个补丁文件数组。因为你设置了patches_dir,所以它会在那里查找。补丁的文件名不是特别的,它可以被压缩。我选择了发行版名称,我的名字作为修补它的人,然后 .patch

---
match:
  module: "Data::Match"
  distribution: "^KSTEPHENS/Data-Match-0.06.tar.gz"
patches:
    - Data-Match-0.06-BDFOY-01.patch

这是你的补丁,备份原始文件,修改目标文件,然后得到统一的diff(或者你的patch能理解的任何东西):

$ diff -u Match.pm.orig Match.pm
--- Match.pm.orig   2022-06-29 15:04:06.000000000 -0400
+++ Match.pm    2022-06-29 14:55:45.000000000 -0400
@@ -965,7 +965,7 @@
     elsif ( $ref eq 'HASH' ) {
       if ( ref($ind) eq 'ARRAY' ) {
    # Not supported by DRef.
-   $str .= $sep . '{' . join(',', @$ind->[0]) . '}';
+   $str .= $sep . '{' . join(',', @{$ind->[0]}) . '}';
       } else {
    $str .= $sep . $ind;
       }

但是您希望在patches目录中使用您指定的名称,因此将输出重定向到此处:

$ diff -u Match.pm.orig Match.pm > /Users/brian/.cpan/patches/Data-Match-0.06-BDFOY-01.patch

如果您想更有趣一些,您可以将该补丁目录放在配置文件的环境变量中,这样您就不必记住它:

$ diff -u Match.pm.orig Match.pm > $CPAN_PATCHES_DIR/Data-Match-0.06-BDFOY-01.patch

现在,当您尝试安装Data::Matchcpan时,它知道它正在安装Data-Match-0.06,它从distroprefs文件中匹配该发行版,并且该distroprefs文件告诉CPAN.pm执行一个操作。在这种情况下,它需要找到补丁文件并应用它。应用补丁后,测试通过,安装成功:

% cpan Data::Match
Reading '/Users/brian/.cpan/Metadata'
  Database was generated on Wed, 29 Jun 2022 05:56:00 GMT
Running install for module 'Data::Match'

______________________ D i s t r o P r e f s ______________________
                  Data-Match-0.06-BDFOY-01.yml[0]
Checksum for /Users/brian/.cpan/sources/authors/id/K/KS/KSTEPHENS/Data-Match-0.06.tar.gz ok
Applying 1 patch:
  /Users/brian/.cpan/patches/Data-Match-0.06-BDFOY-01.patch
  /usr/bin/patch -N --fuzz=3 -p0
patching file Match.pm
Configuring K/KS/KSTEPHENS/Data-Match-0.06.tar.gz with Makefile.PL
Checking if your kit is complete...
Looks good
Generating a Unix-style Makefile
Writing Makefile for Data::Match
Writing MYMETA.yml and MYMETA.json
  KSTEPHENS/Data-Match-0.06.tar.gz
  /usr/local/perls/perl-5.36.0/bin/perl Makefile.PL -- OK
Running make for K/KS/KSTEPHENS/Data-Match-0.06.tar.gz
cp Match.pm blib/lib/Data/Match.pm
cp lib/Sort/Topological.pm blib/lib/Sort/Topological.pm
Manifying 2 pod documents
  KSTEPHENS/Data-Match-0.06.tar.gz
  /usr/bin/make -- OK
Running make test for KSTEPHENS/Data-Match-0.06.tar.gz
PERL_DL_NONLAZY=1 "/usr/local/perls/perl-5.36.0/bin/perl" "-Iblib/lib" "-Iblib/arch" test.pl
1..1
# Running under perl version 5.036000 for darwin
# Current time local: Wed Jun 29 15:54:13 2022
# Current time GMT:   Wed Jun 29 19:54:13 2022
# Using Test.pm version 1.31
ok 1
PERL_DL_NONLAZY=1 "/usr/local/perls/perl-5.36.0/bin/perl" "-MExtUtils::Command::MM" "-MTest::Harness" "-e" "undef *Test::Harness::Switches; test_harness(0, 'blib/lib', 'blib/arch')" t/*.t
t/t1.t .. ok
t/t2.t .. ok
t/t3.t .. 1/15 splice() offset past end of array at /Users/brian/.cpan/build/Data-Match-0.06-15/blib/lib/Data/Match.pm line 1941.
t/t3.t .. ok
t/t4.t .. ok
All tests successful.
Files=4, Tests=182,  0 wallclock secs ( 0.03 usr  0.01 sys +  0.18 cusr  0.04 csys =  0.26 CPU)
Result: PASS

相关问题