可以在安装Perl模块时使用数组作为参考

发布于 2025-02-11 19:01:49 字数 849 浏览 1 评论 0原文

编辑:使用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

,这无济于事。

我应该怎么办?

edit: worked with sudo cpanm Data::Match --force

I'm trying to install the "Data::Match" perl module with ubuntu 18.04.
I use:

perl Makefile.pl
make
make test

And I get the following error:

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

I installed many other modules and they all worked perfectly fine.
I also tried installing with

perl -MCPAN -e shell

and that didn't help.

What should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤独岁月 2025-02-18 19:01:49

data :: Match模块具有一些perl v5.22拧紧的语法。这就是为什么失败的原因。请注意,使用类似的问题安装模块的力量意味着在运行程序时它将失败。

如果可以的话,请勿使用此模块。我不知道它的作用,所以我没有任何替代的建议。

让我们假设您出于某种原因需要这个模块,即使它已经20年了。也许您正在支持您只需要工作的旧应用程序即可。

有这一行( l968> l968 )本身是一个数组参考:

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

应该是划定参考部分的绕组符号:

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

如果您将其更改为 match.pm ,请先运行perl makefile.pl,测试通过(但带有警告),您可以安装模块。

如果您需要的话,您可以在这里停留。

distoprefs

cpan.pm可以处理这些情况,因此您不必每次安装模块时都要进行更改。在CPAN.PM完成工作之前,它可以修补问题分布,建议替换发行版或许多其他事情。您可以使用“ distroprefs”来做到这一点。

有几件事要设置。首先,设置您的distoprefs目录(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,可存储或Data :: Dumper文件。如果YAML(大多数人似乎使用),则需要先安装yaml模块。

这是一个简单的distroprefs文件。它告诉CPAN.PM如何匹配您在CPAN(作者/文件)上看到的分布。在此示例中,它的操作是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;
       }

但是您希望使用您指定的名称的dir中,请重定向在那里:

$ 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 :: Match时,使用CPAN,它知道它正在安装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

The Data::Match module has some syntax that Perl v5.22 tightened up. That's why it fails. Note that force installing a module with an egregious problem like that means it will just fail when you run your program.

If you can, don't use this module. I have no idea what it does, so I don't have any suggestions for a replacement.

Let's suppose you need this module for whatever reason, even though it's 20 years old. Perhaps you're supporting a legacy app that you just need to get working.

There's this line (L968) which dereferences an array element that is itself an array reference:

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

That should be the circumfix notation to delimit the reference part:

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

If you make that change to Match.pm before you run perl Makefile.PL, the tests pass (but with a warning) and you can install the module.

If that's all you need, you can stop here.

Distroprefs

CPAN.pm has a way to handle these situations so you don't have to make the change every time that you want to install the module. Before CPAN.pm does its work, it can patch the problem distribution, suggest a replacement distro, or many other things. You do this with "distroprefs". There are many examples in the CPAN.pm repo.

There are a few things to set up. First, set up your distroprefs directory (o conf init prefs_dir). Second, configure a directory to hold you patches (o conf patches_dir). I choose patches under my .cpan directory, but it can be anything. Save your changes before you exit.

% 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 have two parts. The first specifies what you want to happen. This can be a YAML, Storable, or Data::Dumper file. If YAML (which most people seem to use), then you need to install the YAML module first.

Here's a simple distroprefs file. It tells CPAN.pm how to match a distribution as you'd see it on CPAN (AUTHOR/FILE). In this example, it's action is patches, which is an array of patch files. Since you set up patches_dir, that's where it will look. The file name for the patch isn't special, and it can be compressed. I chose the distro name, my name as the person who patched it, then .patch.

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

Here's your patch. Back up the original file, change the target file, then get the unified diff (or whatever your patch understands):

$ 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;
       }

But you want this in your patches dir with the name that you specified, so redirect the output there:

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

If you want to get really fancy, you could put that patches directory in an environment variable in your profile so you don't have to remember it:

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

Now when you try to install Data::Match with cpan, it knows that it's installing Data-Match-0.06, it matches that distro from a distroprefs file, and that distroprefs file tell CPAN.pm to perform an action. In this case, it needs to find the patch file and apply it. After the patch is applied, the tests pass and the installation succeeds:

% 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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文