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

wolfie7873 has asked for the wisdom of the Perl Monks concerning the following question:

Perl 5.24.1
package NCPS::Results; use strict; use warnings; use lib '/var/www/html/lib' ; use NCPS::UTIL qw/prepareExecute pretty_time getTableColumns input_tim +e convertTime getInfoById / ; use NCPS::Meets qw/getMeetInfo getEventLayout getPointsParadigm getEve +ntLayout2 /; use NCPS::Teams qw/getTeamInfo getAthlete/ ; use NCPS::Events qw/getEventInfo/ ; .... sub getEventResults { my ($event_id,$meet_id,$dbh) = @_; my %results = (); my $team_list = () ; my $sub_meet_having = '' ; my $meet_info = getMeetInfo( $meet_id , $dbh ) ; ....
This code is the backend of a simple web-app. I recently migrated servers, and since then I'm getting an error that defies my understanding. My run-time error is: error:     Undefined subroutine &NCPS::Results::getMeetInfo called at /var/www/html/lib/NCPS/Results.pm line 455. Why is it trying to call a local version of that sub instead of finding in the exported routines included in the use statement. Even when I explicitly add my $meet_info = NCPS::Meets::getMeetInfo ..... I get the same error. What's going on?

Replies are listed 'Best First'.
Re: use statement seemingly ignored
by davido (Cardinal) on Nov 15, 2022 at 20:18 UTC

    At the top of your code, after all the use statements, put the following:

    warn "NCPS::Meets found at $INC{'NCPS/Meets.pm'}\n"; warn "Is NCPS::Meets a subclass of Exporter? ", NCPS::Meets->isa('Exporter') ? "Yes\n" : "No\n"; warn "Can NCPS::Meets export getMeetInfo? ", (0 != grep {$_ eq 'getMeetInfo'} @EXPORT, @EXPORT_OK) ? "Yes\n" : + "No\n";

    This is really only useful if the modules are based on Exporter. There are other export modules out there.

    If this doesn't reveal anything interesting, look at the version of NCPS::Meets that is found at $INC{'NCPS/Meets.pm'} when the code is run from the same invocation that you're getting the errors from. And if this is some sort of a web application, which it appears to be, verify that you've restarted the application. If it's running as mod_perl, make sure Apache has restarted.

    It's unlikely that you would get this error message if the version of NCPS::Meets first found in @INC is an Exporter, and does export getMeetInfo.


    Dave

      I tried what you said thusly:
      package NCPS::Results; use strict; use warnings; use lib '/var/www/html/lib' ; use NCPS::UTIL qw/prepareExecute pretty_time getTableColumns input_tim +e convertTime getInfoById / ; use NCPS::Meets qw/getMeetInfo getEventLayout getPointsParadigm getEve +ntLayout2 /; use NCPS::Teams qw/getTeamInfo getAthlete/ ; use NCPS::Events qw/getEventInfo/ ; use NCPS qw/debug logtime /; use Data::Dumper ; $Data::Dumper::Sortkeys = 1 ; $Data::Dumper::Indent = 1 ; my $debug = 1 ; our (@ISA, @EXPORT_OK); BEGIN { require Exporter; @ISA = qw(Exporter); warn "NCPS::Meets found at $INC{'NCPS/Meets.pm'}\n" ; warn "Is NCPS::Meets a subclass of Exporter? ", NCPS::Meets->isa('Expo +rter') ? "Yes\n" : "No\n" ; warn "Can NCPS::Meets export getMeetInfo? ", (0 != grep { $_ eq 'getMe +etInfo'} @EXPORT_OK) ? "Yes\n" : "No\n" ; @EXPORT_OK = qw/ getTeamIdFromAbbr getMeetResults getTeamResults getResultDetail insertResult insertSplits insertRelay insertLeadoff getEventResults sortEventResults getScores getEventScores setEventScore updateMeetScores setMeetScore getCumulativeScores getPerformancePoints convertMeetToNWayDual scoreEvent addScoresAfterTheFact setResultScoreAndPlace deleteResult getEventIDFromResultRecord getLeadOffSplit updateMeetTimeStamp /; }
      And I tested the module syntax command-line:
      root@ncps-modperl-prod:/var/www/html/lib/NCPS# perl -ctw Results.pm NCPS::Meets found at /var/www/html/lib/NCPS/Meets.pm Is NCPS::Meets a subclass of Exporter? No Can NCPS::Meets export getMeetInfo? No NCPS::Meets found at /var/www/html/lib/NCPS/Meets.pm Is NCPS::Meets a subclass of Exporter? Yes Can NCPS::Meets export getMeetInfo? No Subroutine getPerformancePoints redefined at Results.pm line 58. Subroutine getTeamIdFromAbbr redefined at Results.pm line 104. Subroutine getMeetResults redefined at Results.pm line 112. Subroutine getTeamResults redefined at Results.pm line 126. Subroutine getResultDetail redefined at Results.pm line 256. Subroutine insertResult redefined at Results.pm line 296. Subroutine insertSplits redefined at Results.pm line 389. Subroutine insertRelay redefined at Results.pm line 421. Subroutine getEventResults redefined at Results.pm line 453. Subroutine sortEventResults redefined at Results.pm line 650. Subroutine getEventScores redefined at Results.pm line 718. Subroutine scoreEvent redefined at Results.pm line 745. Subroutine updateMeetTimeStamp redefined at Results.pm line 854. Subroutine getScores redefined at Results.pm line 863. Subroutine setEventScore redefined at Results.pm line 888. Subroutine updateMeetScores redefined at Results.pm line 919. Subroutine setMeetScore redefined at Results.pm line 939. Subroutine getCumulativeScores redefined at Results.pm line 988. Subroutine convertMeetToNWayDual redefined at Results.pm line 1016. Subroutine addScoresAfterTheFact redefined at Results.pm line 1098. Subroutine setResultScoreAndPlace redefined at Results.pm line 1132. Subroutine deleteResult redefined at Results.pm line 1147. Subroutine getEventIDFromResultRecord redefined at Results.pm line 117 +3. Subroutine getLeadOffSplit redefined at Results.pm line 1194. Subroutine insertLeadoff redefined at Results.pm line 1254. Results.pm syntax OK
      I double checked Meets.pm here:
      package NCPS::Meets; use strict; use warnings; use feature qw( switch ); no warnings qw( experimental::smartmatch ); use lib '/var/www/html/lib' ; use NCPS qw/ debug / ; use NCPS::UTIL qw/prepareExecute display_event display_event2 getInfoB +yId/ ; use NCPS::Teams qw/getTeamInfo/ ; my $debug = 1 ; our (@ISA, @EXPORT_OK); BEGIN { require Exporter; @ISA = qw(Exporter); @EXPORT_OK = qw/ createMeet addMeetDirector addTeamsToMeet setupEventScores getEventStatus changeEventStatus getMeetInfo getMeetRoster getEventLayout getEventLayout2 getMyMeets getPointsParadigm getAllEventLayouts getAllScoringLayouts getAllFacilities getSubMeets getEventIDFromEventOrder getPointsLayout checkMeetId clearMeet getMeetsToEnter addDiveCat pastDeadline getReferees getMeetsToCertify getOfficials /; }
      I'm guessing all those redefined statements indicate a rather serious problem somewhere. I'll follow that thread.

        Why are you getting the output twice?

        NCPS::Meets found at /var/www/html/lib/NCPS/Meets.pm Is NCPS::Meets a subclass of Exporter? No Can NCPS::Meets export getMeetInfo? No NCPS::Meets found at /var/www/html/lib/NCPS/Meets.pm Is NCPS::Meets a subclass of Exporter? Yes Can NCPS::Meets export getMeetInfo? No Subroutine getPerformancePoints redefined at Results.pm line 58. Subroutine getTeamIdFromAbbr redefined at Results.pm line 104. Subroutine getMeetResults redefined at Results.pm line 112.

        Why are you getting "redefined" warnings?

        How is NCPS::Results getting loaded (twice)?

        Notice how you're getting two different answers to the same question, presumably because a redefinition has happened?

        Is NCPS::Meets a subclass of Exporter? No ... Is NCPS::Meets a subclass of Exporter? Yes

        Dave

Re: use statement seemingly ignored
by haukex (Archbishop) on Nov 15, 2022 at 20:52 UTC
    I recently migrated servers, and since then I'm getting an error

    That's clearly not the only thing that has changed. Have you made sure the code on the old server is identical to the new server? If not, what changes have you made? If the code truly is identical, then make sure to check the Perl versions on the old and new servers, as well as the contents of @INC on each, and report those here too.

    Does NCPS::Meets use the standard Exporter module? Because if it does, it would complain about that module not exporting getMeetInfo, or if it did export it but the module didn't actually contain that function, my testing shows the error message would be different.

    It would be best if you could show an SSCCE that reproduces the error.

Re: use statement seemingly ignored
by ikegami (Patriarch) on Nov 15, 2022 at 21:12 UTC

    Why is it trying to call a local version of that sub instead of finding in the exported routines included in the use statement.

    Importing a sub literally places it in the importing namespace. So if getMeetInfo had been imported into NCPS::Results, it would be found at NCPS::Results::getMeetInfo.

    I suspect you have modules that directly or indirectly import each other, and that this is the cause of the problem.

      The OP tells us that he tried the workaround of using the fully qualified name in the call and got the same error message. Does this not tell us that the function is not only not imported, but not even defined (at least not at the time it is called)? His conclusion that his use statement was ignored is at least reasonable. I suspect that you are right about the modules using each other. The documentation Perl Modules recommends require rather than use in this case. Can you explain?
      Bill

        Does this not tell us that the function is not only not imported, but not even defined

        The error message from the OP tells us it wasn't defined.

        Neither the error message or the fact that using the full qualified name works tells us whether it was imported or not.

        But it does strongly suggest the problem is that it wasn't imported, yes. The two most likely causes of that is buggy/missing exporting logic, or modules that (directly or indirectly) use each other.

Re: use statement seemingly ignored
by Corion (Patriarch) on Nov 15, 2022 at 19:54 UTC

    Are you sure that NCPS::Meets exports the getMeetInfo() subroutine?

    Are you sure that there is no NCPS::Results::getMeetInfo() subroutine?

    Also, maybe getMeetInfo has code that outputs that error message?

    Without seeing more of the code and what line 455 is, it's hard to tell. Consider removing as much code as possible, while still keeping a working SSCCE.

      NCPS::Meets::getMeetInfo could be calling into NCPS::Results.pm which calls NCPS::Results::getMeetInfo which doesn't exist. There is nothing in the OP's error report that would tell us and metacpan doesn't seem to know a lot about NCPS so its hard to check.

      Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: use statement seemingly ignored
by GrandFather (Saint) on Nov 15, 2022 at 19:57 UTC

    I know nothing about the module or where it might usually live, but your results are consistent with there being a copy in the path specified by your use lib '/var/www/html/lib' ; line. I don't understand what you mean by "call a local version". Maybe the module version is different than you expect and there have been API changes?

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: use statement seemingly ignored
by haj (Vicar) on Nov 15, 2022 at 20:05 UTC
    Probably there's something wrong with how NCPS::Meets exports its symbols. So, examine that module and check whether it offers an import method, or if it doesn't, which of the modules used by NCPS::Meets does the exporting. CPAN has quite some exporter modules, and perhaps the old and new servers have different versions of your exporter module available.
Re: use statement seemingly ignored
by cavac (Vicar) on Nov 17, 2022 at 15:03 UTC