in reply to Undefined import name priority issue?

Line 12 of JSON::WebToken is:

use JSON qw(encode_json decode_json);

Perl's use statement is shorthand for:

BEGIN { require JSON; JSON->import(qw(encode_json decode_json)); }

.. and the key feature of require is that it loads the module only if it has not already been loaded. It checks that by looking in %INC.

My guess then is that JSON::XS is poking a value into %INC to make it look as if JSON itself has also already been loaded - but failing to define the JSON::import() method.

In the JSON::XS SYNOPSIS section I see:

# Note that JSON version 2.0 and above will automatically use JSON:: +XS # if available, at virtually no speed overhead either, so you should # be able to just: use JSON; # and do the same things, except that you have a pure-perl fallback +now.

.. so I suspect if you change your mylib::json to use JSON instead of use JSON::XS, it will probably make the problem disappear. If my diagnosis is correct, though, I'd call this a bug in JSON::XS.

Replies are listed 'Best First'.
Re^2: Undefined import name priority issue?
by sectokia (Friar) on Apr 08, 2025 at 03:31 UTC

    The issue seems to be the existance of a file in mylib with name 'json.pm'

    The problem surface even with this extremely simple setup:

    mylib/json.pm:

    package mylib::json;1;

    mylib.pm:

    package mylib; use lib 'mylib'; 1;

    test.pl:

    use strict; use warnings; use lib '.'; use mylib; use JSON::WebToken;

    output:

    Attempt to call undefined import method with arguments ("encode_json" +...) via package "JSON" (Perhaps you forgot to load the package?) at +C:/Strawberry/perl/site/lib/JSON/WebToken.pm line 12.

    I assume JSON::WebToken or JSON/JSON::XS is looking in path for json.pm file and getting confused? As long as I don't use the name json.pm there is no problem.

      The issue seems to be the existance of a file in mylib with name 'json.pm'

      No, half of the issue is that you are doing this:

      use lib 'mylib'; use mylib::json;

      You add the "mylib" directory to the module search path (@INC). In that case, your module should be simply named json and not mylib::json. If you want to load it as mylib::json, don't add the "mylib" directory to @INC, but the directory containing the "mylib" directory (i.e. "."). Older perls already include "." in @INC, that's why it probably works at all.

      The second part of the issue is that your filesystem is not case sensitive. Do you see any difference between json and JSON? I see four different bits, but your filesystem does not. So when perl attempts to load "JSON.pm" containing the JSON package, it is fed "json.pm" containing the mylib::json package instead.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        Thanks: that is it exactly... should not have "use lib 'mylib';" at all, isn't needed because I want mylib.pm to reference mylib::json.

      You are on MS Windows where the default filesystem is case insensitive. Blame Microsoft (again).


      🦛