in reply to help with "symbol lookup error" message

The error references the List::Util module, but doesn't occur unless I add the "use File::Copy", ...

The odd thing there is that List::Util is being referenced, but I don't see how List::Util (which is quite separate from List::MoreUtils) gets loaded.

If your account of what's happening is accurate, then the only explanation I can think of is that, on your system, using File::Copy leads to the loading of List::Util (either by "use" or "require"), and the incompatible List::Util intalled in /home/user_foo/perl_modules/lib/perl5 is the one that gets found.

On my system, use File::Copy does not lead to List::Util being loaded - but File::Copy probably does some things differently on different systems.

If you want to check which modules have been loaded by your script (and where they were found), just add the following line at the end of your script:
for(keys %INC) { print "$_: $INC{$_}\n" };
If placed at the end of the script, that will not only tell you the modules that were loaded by "use", but also any modules that were subsequently loaded via "require" during the running of your script. (That's assuming, of course, that the script runs to completion ;-)

Cheers,
Rob

Replies are listed 'Best First'.
Re^2: help with "symbol lookup error" message
by hippo (Archbishop) on Jan 27, 2023 at 10:36 UTC
    (That's assuming, of course, that the script runs to completion ;-)

    Since that's the problem facing Special_K perhaps using a coderef in @INC will be a more useful strategy in this instance*.

    #!/usr/bin/env perl use strict; use warnings; BEGIN { unshift @INC, sub { warn "Loading $_[1]\n"; 0; }; } use File::Copy;

    When I run this (with File::Copy 2.35 on perl 5.34.0 on Linux) the result is:

    Loading File/Copy.pm Loading File/Spec.pm Loading File/Spec/Unix.pm Loading Cwd.pm Loading Exporter.pm Loading XSLoader.pm Loading constant.pm Loading warnings/register.pm Loading Config.pm Loading Time/HiRes.pm Loading Exporter/Heavy.pm Loading Scalar/Util.pm Loading List/Util.pm Loading overload.pm Loading overloading.pm

    So List::Util is in there on my platform right enough.

    * I'm sure there's a module for this but I can neither remember nor find it just now.


    🦛

      So List::Util is in there on my platform right enough

      Aaah ... cool.
      AFAICS, this absurd dependency is not present in perl-5.36.0 - on both Windows and freebsd-12.0.
      On Windows (perl-5.36.0), your script outputs:
      Loading File/Copy.pm Loading builtin.pm Loading overload.pm Loading overloading.pm Loading warnings/register.pm Loading File/Spec.pm Loading File/Spec/Win32.pm Loading Cwd.pm Loading Exporter.pm Loading XSLoader.pm Loading File/Spec/Unix.pm Loading constant.pm Loading Config.pm Loading Time/HiRes.pm Loading Carp.pm
      On freebsd (5.36.0), it's exactly the same - except that Carp.pm and File/Spec/Win32.pm are not loaded, and Exporter/Heavy.pm is loaded.

      I'm sure there's a module for this but I can neither remember nor find it just now

      I reckon the code you posted is much clearer for not having loaded that module (whatever it is ;-)

      Cheers,
      Rob

        Thanks for providing your list. I've dug a little further and for me the chain to List::Util appears to be just File::Copy -> Scalar::Util -> List::Util with File::Copy having this line:

        my $Scalar_Util_loaded = eval q{ require Scalar::Util; require overloa +d; 1 };

        This explains why I'm seeing it but not why it is absent in your case. I'll leave that part to you. :-)


        🦛

      This question is tangential to my main issue, but since I've never seen the code before, could you please explain what exactly this is doing:

      unshift @INC, sub { warn "Loading $_[1]\n"; 0; };

      It looks like it's creating an array of subroutines, where each subroutine just prints the same element (1). The 0 I'm guessing is just a required return value? I must be missing something here.

        @INC hooks are described under require. To simplify, this will output all the modules your running program is trying to load.

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
        > The 0 I'm guessing is just a required return value?

        The zero is not required.

        unshift @INC, sub { warn "Loading $_[1]\n" };
        Does the same thing.
        > what exactly this is doing

        I don't know but hacked it to make this cool error message:

        perl -Mstrict -le 'BEGIN{unshift@INC,sub{$$_[1]}};use Math::Trig'
        Warning: failed to load Config_git.pl, something strange about this perl...

      > When I run this (with File::Copy 2.35 on perl 5.34.0 on Linux) the result is:


      Is File::Copy versioned separately from Perl itself? When I look at the CPAN page it looks like File::Copy shares the version number of the perl distribution it is included with (unless I'm interpreting the webpage wrong):

      https://metacpan.org/pod/File::Copy
      So what's happening is that in perl 5.34.0 and earlier, a module that is included with Perl by default (File::Copy) is calling a module that is not (List::Util)? And then perl 5.36 removed this dependency?
        Is File::Copy versioned separately from Perl itself? When I look at the CPAN page it looks like File::Copy shares the version number of the perl distribution it is included with

        File::Copy is a core module which means that it is bundled and shipped with Perl. However, the core modules do not share their version numbers with the corresponding Perl version. The page you linked contains both the version number of Perl (in the crumbtrail at the top of the main div) and the different version number for File::Copy (at the top of the left margin). For core modules, Perl itself is the dist but each contained module is versioned separately.

        So what's happening is that in perl 5.34.0 and earlier, a module that is included with Perl by default (File::Copy) is calling a module that is not (List::Util)? And then perl 5.36 removed this dependency?

        Yes, with the exception that List::Util is a core module too. See modules for the full list of core modules.


        🦛

        When doing this sort of investigation, I find the core utility corelist to be very useful. This has a number of options; here's a selection of examples:

        $ corelist File::Copy Data for 2022-05-27 File::Copy was first released with perl 5.002 $ corelist -v 5.034000 File::Copy File::Copy 2.35 $ corelist -a File::Copy Data for 2022-05-27 File::Copy was first released with perl 5.002 5.002 1.5 ... v5.34.0 2.35 ... v5.36.0 2.39

        Note that some modules have been added then removed from core:

        $ corelist CGI Data for 2022-05-27 CGI was first released with perl 5.004, deprecated (will be CPAN-only) + in v5.19.7 and removed from v5.21.0

        If it's important to you, perlhist gives the date of Perl releases.

        Modules which are core, but do not have a separate CPAN version, will show perl-<version> as the distribution when you search for them using MetaCPAN; for instance, "MetaCPAN: File::Copy" gives:

        Ricardo SIGNES / perl-5.36.0 / File::Copy

        On the left-hand panel, under TOOLS, the Download link points to the tarball: 'https://cpan.metacpan.org/authors/id/R/RJ/RJBS/perl-5.36.0.tar.gz'. You can't install this module separately from CPAN.

        Modules which are core, but also have a separate CPAN version, show a distribution which is not perl-<version>; it may reflect the module name, e.g. Some-Module-<version>, or it may be part of a bundle of modules under a different name, e.g. Various-Modules-<version>. For instance:

        $ corelist List::Util Data for 2022-05-27 List::Util was first released with perl v5.7.3 $ corelist -a List::Util | tail -2 v5.36.0 1.62

        From "MetaCPAN: List::Util":

        Paul Evans / Scalar-List-Utils-1.63 / List::Util

        The distribution name is a link. Follow this to get additional information, including a list of bundled modules.

        Also under TOOLS (left-hand panel) there's a "Jump to version" dropdown list: possibly useful if you want to install an older version from CPAN.

        — Ken

      #!/usr/bin/perl use strict; use warnings; BEGIN { unshift @INC, sub { warn "Loading $_[1]\n"; push @ARGV, $_[1] } } use File::Copy; print "$^V\n"; print "$_\n" for sort {lc $a cmp lc $b} @ARGV; __END__ v5.18.2 Config.pm Exporter.pm File/Copy.pm File/Spec.pm File/Spec/Unix.pm List/Util.pm overload.pm overloading.pm Scalar/Util.pm vars.pm warnings/register.pm XSLoader.pm > constant.pm > DynaLoader.pm v5.20.3 Config.pm constant.pm DynaLoader.pm Exporter.pm File/Copy.pm File/Spec.pm File/Spec/Unix.pm List/Util.pm overload.pm overloading.pm Scalar/Util.pm vars.pm warnings/register.pm XSLoader.pm < DynaLoader.pm > Cwd.pm v5.26.2 Config.pm constant.pm Cwd.pm Exporter.pm File/Copy.pm File/Spec.pm File/Spec/Unix.pm List/Util.pm overload.pm overloading.pm Scalar/Util.pm vars.pm warnings/register.pm XSLoader.pm < vars.pm > Exporter/Heavy.pm > Time/HiRes.pm v5.28.0 Config.pm constant.pm Cwd.pm Exporter.pm Exporter/Heavy.pm File/Copy.pm File/Spec.pm File/Spec/Unix.pm List/Util.pm overload.pm overloading.pm Scalar/Util.pm Time/HiRes.pm warnings/register.pm XSLoader.pm < List/Util.pm < Scalar/Util.pm > builtin.pm v5.36.0 builtin.pm Config.pm constant.pm Cwd.pm Exporter.pm Exporter/Heavy.pm File/Copy.pm File/Spec.pm File/Spec/Unix.pm overload.pm overloading.pm Time/HiRes.pm warnings/register.pm XSLoader.pm

      Is it possible to modify this code to see where the modules are being called from? For example, to see that List/Util.pm is being called by File/Copy.pm?

        Sure, we can use caller to do that:

        #!/usr/bin/env perl use strict; use warnings; BEGIN { unshift @INC, sub { warn "Loading $_[1] from " . (caller)[0] . "\n +"; 0; }; } use File::Copy;

        🦛

Re^2: help with "symbol lookup error" message
by xiaoyafeng (Deacon) on Feb 02, 2023 at 04:17 UTC

    If you want to check which modules have been loaded by your script (and where they were found), just add the following line at the end of your script: for(keys %INC) { print "$_: $INC{$_}\n" };

    I recommend using perldebug, which is more clear and simple:
    perl -MFile::copy -de0 DB<1> M 'Carp.pm' => '1.50 from C:/Strawberry/perl/lib/Carp.pm' 'Config.pm' => '5.032001 from C:/Strawberry/perl/lib/Config.pm' 'Config_git.pl' => 'C:/Strawberry/perl/lib/Config_git.pl' 'Config_heavy.pl' => 'C:/Strawberry/perl/lib/Config_heavy.pl' 'Cwd.pm' => '3.78 from C:/Strawberry/perl/lib/Cwd.pm' 'DynaLoader.pm' => '1.47_01 from C:/Strawberry/perl/lib/DynaLoader.pm' 'Exporter.pm' => '5.74 from C:/Strawberry/perl/lib/Exporter.pm' 'File/Spec.pm' => '3.78 from C:/Strawberry/perl/lib/File/Spec.pm' 'File/Spec/Unix.pm' => '3.78 from C:/Strawberry/perl/lib/File/Spec/Uni +x.pm' 'File/Spec/Win32.pm' => '3.79 from C:/Strawberry/perl/lib/File/Spec/Wi +n32.pm' 'File/copy.pm' => 'C:/Strawberry/perl/lib/File/copy.pm' 'IO.pm' => '1.45 from C:/Strawberry/perl/lib/IO.pm' 'IO/Handle.pm' => '1.45 from C:/Strawberry/perl/lib/IO/Handle.pm' 'List/Util.pm' => '1.55 from C:/Strawberry/perl/lib/List/Util.pm' 'Scalar/Util.pm' => '1.55 from C:/Strawberry/perl/lib/Scalar/Util.pm' 'SelectSaver.pm' => '1.02 from C:/Strawberry/perl/lib/SelectSaver.pm' 'SelfLoader.pm' => '1.26 from C:/Strawberry/perl/lib/SelfLoader.pm' 'Symbol.pm' => '1.08 from C:/Strawberry/perl/lib/Symbol.pm' 'Term/Cap.pm' => '1.17 from C:/Strawberry/perl/lib/Term/Cap.pm' 'Term/ReadKey.pm' => '2.38 from C:/Strawberry/perl/vendor/lib/Term/Rea +dKey.pm' 'Term/ReadLine.pm' => '1.17 from C:/Strawberry/perl/lib/Term/ReadLine. +pm' 'Term/ReadLine/Perl.pm' => '1.0303 from C:/Strawberry/perl/vendor/lib/ +Term/ReadLine/Perl.pm' 'Term/ReadLine/readline.pm' => '1.0303 from C:/Strawberry/perl/vendor/ +lib/Term/ReadLine/readline.pm' 'Time/HiRes.pm' => '1.9764 from C:/Strawberry/perl/lib/Time/HiRes.pm' 'Win32.pm' => '0.54 from C:/Strawberry/perl/lib/Win32.pm' 'XSLoader.pm' => '0.30 from C:/Strawberry/perl/lib/XSLoader.pm' 'constant.pm' => '1.33 from C:/Strawberry/perl/lib/constant.pm' 'feature.pm' => '1.58 from C:/Strawberry/perl/lib/feature.pm' 'overload.pm' => '1.31 from C:/Strawberry/perl/lib/overload.pm' 'overloading.pm' => '0.02 from C:/Strawberry/perl/lib/overloading.pm' 'perl5db.pl' => '1.57 from C:/Strawberry/perl/lib/perl5db.pl' 'strict.pm' => '1.11 from C:/Strawberry/perl/lib/strict.pm' 'vars.pm' => '1.05 from C:/Strawberry/perl/lib/vars.pm' 'warnings.pm' => '1.47 from C:/Strawberry/perl/lib/warnings.pm' 'warnings/register.pm' => '1.04 from C:/Strawberry/perl/lib/warnings/r +egister.pm'




    I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction