http://qs321.pair.com?node_id=11149923


in reply to Re: help with "symbol lookup error" message
in thread help with "symbol lookup error" message

(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.


🦛

Replies are listed 'Best First'.
Re^3: help with "symbol lookup error" message
by syphilis (Archbishop) on Jan 27, 2023 at 12:11 UTC
    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 explains why I'm seeing it but not why it is absent in your case. I'll leave that part to you. :-)

        Heh ... yeah, fair enough ;-)
        AFAICT it's pretty simple. By the time perl-5.36.0 comes along, Sawyer has removed the Scalar::Util requirement from File/Copy.pm.

        Frid'y night (alcohol-fuelled) aside: Given the ease with which perl can be built & installed, and that perl-5.38.0 is only a few months away, I'm surprised that serious perl-users are still running perl-5.34.x.
        I see it as being symptomatic of the mentality expressed poignantly by Frank Zappa in "A Token of My Extreme" (Joe's Garage):
        Some people think that if they go too far, they'll never get back to w +here the rest of them are.
        Cheers,
        Rob
Re^3: help with "symbol lookup error" message
by Special_K (Monk) on Jan 27, 2023 at 23:12 UTC

    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...
Re^3: help with "symbol lookup error" message
by Special_K (Monk) on Jan 28, 2023 at 18:01 UTC

    > 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.


      🦛

        So in my example, which uses 5.20.0, File::Copy is calling List::Util, but is finding the version installed at /home/user_foo/perl_modules/lib/perl5, rather than the version installed at a location corresponding to (and compatible with) 5.20.0. Is that correct? Is it possible to tell perl to use one path for a specific module but use another path (or set of paths) for other 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

Re^3: help with "symbol lookup error" message
by Anonymous Monk on Feb 02, 2023 at 11:23 UTC
    #!/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
Re^3: help with "symbol lookup error" message
by Special_K (Monk) on Feb 03, 2023 at 20:41 UTC

    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;

      🦛