I'm having an issue with a script I'm trying to write, I am writing a CLI menu system, where the menu definitions are being stored in an XML file. I am trying to pass a subroutine to the script to run, but I keep getting an Undefined subroutine, even though it exists within the same module its being processed from. Can someone determine what I'm doing wrong? Why is MenuNA being undefined?

script I'm running from (ScriptLibsMenu):

#!/usr/bin/perl use strict; use lib ("/home/jsmith/lib"); use ScriptLibs::Menu; my $DEBUG='1'; my $MENUFILE='/home/jsmith/etc/MENU.example.main'; my $MENU=''; MenuGen($DEBUG,"$MENUFILE");

Module I'm calling (ScriptLibs::Menu.pm):

package ScriptLibs::Menu; # VERSION: 1444685500 #use Time::localtime; #use File::Basename; use strict; use warnings; #################### subroutine header begin #################### =head1 NAME: ScriptLibs::Utils =head1 SYNOPSIS: use ScriptsList::Func_DEBUG; Func_DEBUG("DEBUGCONTROL","DEBUGMESSAGELEVEL","DEBUGMESSAGE"); =head1 DESCRIPTION: DEBUG Utility used with Scripts =head1 USAGE: =cut #################### subroutine header end #################### BEGIN { use Exporter (); use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); $VERSION = '1444685500'; @ISA = qw(Exporter); #Give a hoot don't pollute, do not export more than needed by defa +ult @EXPORT = qw(MenuGen MenuNA); @EXPORT_OK = qw(all); # %EXPORT_TAGS = (all => [qw(test_one test_two)]); %EXPORT_TAGS = ( Functions => [ qw(MenuGen MenuNA) ], Variables => [ qw($FUNCNAME $HOSTNAME $LOGDATE $VE +RSION) ], ); } use File::Basename; use IO::File; use XML::Simple qw(:strict); my $CLEAR=`clear`; my $clear=`clear`; my $DEBUG=''; my $SRCNAME=''; my $ETCPATH=''; my $FUNCNAME=''; my $TAILLINE=''; my $LIBNAME="ScriptLibs::Menu"; my $MENUBOB='1'; use ScriptLibs::Debug('Func_DEBUG'); use ScriptLibs::ScrIO('Func_Error','Func_Entry','Func_Pause'); use ScriptLibs::Usage('Func_Usage'); sub MenuNA { #NOTE: Not Available my $FUNCNAME='MenuNA'; Func_Pause("Menu Option is not available in this release"); } #END MenuNA; sub Func_MenuReturn { #NOTE: Exits the script my $FUNCNAME='Func_MenuReturn'; print "FUNCNAME=$FUNCNAME"; $MENUBOB='2'; } #END MenuNA; sub Func_MenuExit { #NOTE: Exits the script my $FUNCNAME='Func_MenuExit'; exit; } #END Func_MenuExit; sub Func_MenuLogout { #NOTE: Exits the script my $FUNCNAME='Func_MenuLogout'; my $SCRIPTNAMETEMP=$0; my $SCRIPTNAME=basename($SCRIPTNAMETEMP); my $PSEARCH1=''; my $PTY=''; my $PSEARCH2=''; #print "SCRIPTNAME=$SCRIPTNAME\n"; my @PS1=split(/\n/, `/bin/ps -ef | /bin/grep $SCRIPTNAME`); foreach my $line (@PS1) { chomp $line; #print "line=$line\n"; if ( $line =~ /sh -c \/bin\/ps -ef/ && $line =~/$SCRIPTNAME/ ) + { my @ARRAY=split(/\s+/, $line); $PSEARCH1=$ARRAY[2]; $PTY=$ARRAY[5]; last; } else { next; } } #print "PSEARCH1=$PSEARCH1\n"; foreach my $line2 (@PS1) { chomp $line2; my @ARRAY2=split(/\s+/, $line2); if ( $ARRAY2[1] =~ /$PSEARCH1/ && $ARRAY2[5] =~/$PTY/ ) { #print "line2=$line2\n"; $PSEARCH2=$ARRAY2[2]; last; } else { next; } } #print "PSEARCH2=$PSEARCH2\n"; my @PS2=split(/\n/, `/bin/ps -ef | /bin/grep $PTY`); foreach my $line3 (@PS2) { chomp $line3; #print "line3=$line3\n"; my @ARRAY3=split(/\s+/, $line3); if ( $ARRAY3[1] =~ /^$PSEARCH2$/ && $ARRAY3[5] =~ /$PTY/ ) { my $YESNO=Func_Entry("$DEBUG","Are you sure you wish to lo +gout?","(Y/N)","N","menu"); chomp $YESNO; if ( uc($YESNO) =~ /^Y/ ) { `/usr/bin/kill -9 $PSEARCH2`; } last; } else { next; } } } #END Func_MenuLogout; sub MenuGen { #NOTE: Generates a Menu my $FUNCNAME='MenuGen'; my $MENUFILE=''; my $MENU=''; my %COMMANDS; my %HELPS; my $CURSOR; if ($_[0]) { $DEBUG=$_[0]; chomp $DEBUG; } if ($DEBUG) { Func_DEBUG("$DEBUG","1","$FUNCNAME"); } #DEBUG if ($_[1]) { $MENUFILE=$_[1]; chomp $MENUFILE; } else { Func_Error("1","Must supply a menufile to $FUNCNAME"); } if ( -e "$MENUFILE" ) { #print "MENUFILE=$MENUFILE\n"; $MENU=XMLin($MENUFILE, forcearray => [ qw(OPTION SELECT TEXT C +OMMAND HELP) ], keyattr => [] ); #use Data::Dumper; #print Dumper($MENU); my $MENUBOB='1'; while ($MENUBOB eq '1') { print "$CLEAR"; print "$MENU->{TITLE}\n"; foreach my $SUB ($MENU->{SUBTITLE}) { chomp $SUB; if ( $SUB =~ /ARRAY/ ) { foreach my $BOB (@$SUB) { print " $BOB\n"; } } else { print " $SUB\n"; } } #END foreach my $SUB ($MENU->{SUBTITLE}) print "\n"; foreach my $MENOPT ($MENU->{OPTION}) { chomp $MENOPT; my $SELECT=''; my $TEXT=''; my $POPHELP=''; my $POPCOMM=''; foreach my $BOB (@$MENOPT) { foreach my $BOB2 (keys (%$BOB)) { chomp $BOB2; #print "BOB2=$BOB2 $$BOB{$BOB2}->[0]\n"; if ( $BOB2 =~ /SELECT/ ) { $SELECT=$$BOB{$BOB2}->[0]; chomp $SELECT; next; } elsif ( $BOB2 =~ /TEXT/ ) { $TEXT=$$BOB{$BOB2}->[0]; chomp $TEXT; next; } elsif ( $BOB2 =~ /HELP/ ) { $POPHELP=$$BOB{$BOB2}->[0]; chomp $TEXT; next; } elsif ( $BOB2 =~ /COMMAND/ ) { $POPCOMM=$$BOB{$BOB2}->[0]; chomp $TEXT; next; } else { } } #END foreach my $BOB2 (keys (%$BOB)) if ( $SELECT =~ /^H/ ) { print "\n $SELECT - $TEXT\n"; $COMMANDS{"$SELECT"}="\\\&$POPCOMM"; $HELPS{"$SELECT"}="$POPHELP"; } elsif ( $SELECT =~ /^X/ ) { print " $SELECT - $TEXT\n\n"; $COMMANDS{"$SELECT"}="$POPCOMM"; $HELPS{"$SELECT"}="$POPHELP"; } else { print " $SELECT - $TEXT\n"; $COMMANDS{"$SELECT"}="\\\&$POPCOMM"; $HELPS{"$SELECT"}="$POPHELP"; } } #END foreach my $BOB (@$MENOPT) } #END foreach my $MENOPT ($MENU->{OPTION}) $CURSOR=$MENU->{'CURSOR'}; my $ENTRY=Func_Entry("$DEBUG","Enter your selection","$CU +RSOR","X","menu"); chomp $ENTRY; if ($ENTRY =~ /^[0-9]/ ) { print "$COMMANDS{$ENTRY}\n"; if ( $COMMANDS{$ENTRY} =~ /SUBMENU/ ) { my @ARRAY=split(/\s+/, $COMMANDS{$ENTRY}); my $SUBMENUFILE=$ARRAY[1]; $SUBMENUFILE=~s/^SUBMENU //; MenuGen($DEBUG,"$SUBMENUFILE"); } else { my $RUNNCOMMAND=$COMMANDS{$ENTRY}; my $RUNBOB=\&$RUNNCOMMAND; &$RUNBOB(); } } elsif ( $ENTRY =~ /^H/i ) { my $HELPME=$ENTRY; $HELPME=~s/^[Hh]//; Func_Usage("$HELPS{$HELPME}"); } elsif ( $ENTRY =~ /^x/i || $ENTRY =~ /^q/i ) { my $RUNNCOMMAND=$COMMANDS{'X'}; #print "RUNNCOMMAND=$RUNNCOMMAND\n";; if ( $RUNNCOMMAND =~ /return/i ) { $MENUBOB='2'; } elsif ( $RUNNCOMMAND =~ /exit/i ) { exit; } elsif ( $RUNNCOMMAND =~ /logout/i ) { Func_MenuLogout(); } else { } } else { Func_Error('2',"You have entered an invalid option"); } } #END while ($BOB eq '1') } else { Func_Error("1","Menu definitiion file $MENUFILE does not exist +"); } } #END MenuGen #n pod documentation begin ################### ## Below is the stub of documentation for your module. ## You better edit it! #=head1 NAME #Test - Blank Module #=head1 SYNOPSIS # use Test; # blah blah blah #=head1 DESCRIPTION # #Stub documentation for this module was created by ExtUtils::ModuleMak +er. #It looks like the author of the extension was negligent enough #to leave the stub unedited. #Blah blah blah. # #=head1 USAGE #=head1 BUGS #=head1 SUPPORT #=head1 HISTORY #0.01 Fri Aug 29 10:12:08 2008 # - original version; created by ExtUtils::ModuleMaker 0.51 # #=head1 AUTHOR # James M Smith #=head1 COPYRIGHT #This program is free software; you can redistribute #it and/or modify it under the same terms as Perl itself. #The full text of the license can be found in the #LICENSE file included with this module. #=head1 SEE ALSO #perl(1). #=cut #################### main pod documentation end ################### 1; # The preceding line will help the module return a true value

The XML file (MAIN.example.main)

<MENU> <TITLE>Configuration Wizard </TITLE> <SUBTITLE>Enter a menu option to begin</SUBTITLE> <OPTION> <SELECT>1</SELECT> <TEXT>Configure System Administrator Password</TEXT> <COMMAND>1</COMMAND> <HELP>PASSWD CHANGE \n Change the Administrator password</HELP> </OPTION> <OPTION> <SELECT>2</SELECT> <TEXT>Configure Network Parameters</TEXT> <COMMAND>SUBMENU /home/jsmith/etc/MENU.example.NetConfig</COMMAND +> <HELP>Set the IP, netmask, gateway, and configure various network + services</HELP> </OPTION> <OPTION> <SELECT>3</SELECT> <TEXT>Test TCP Network Settings</TEXT> <COMMAND>11</COMMAND> <HELP>Ping, nslookup, etc</HELP> </OPTION> <OPTION> <SELECT>4</SELECT> <TEXT>Manage Processes</TEXT> <COMMAND>11</COMMAND> <HELP>Start, Stop KO</HELP> </OPTION> <OPTION> <SELECT>5</SELECT> <TEXT>Manage Physical Server</TEXT> <COMMAND>Reboot</COMMAND> <HELP>Reboot, Power cycle, manage physical drives</HELP> </OPTION> <OPTION> <SELECT>6</SELECT> <TEXT>Shell (sh)</TEXT> <COMMAND>MenuNA</COMMAND> <HELP>Not available at this time.</HELP> </OPTION> <OPTION> <SELECT>H#</SELECT> <TEXT>Help(number) for more details</TEXT> <COMMAND>11</COMMAND> </OPTION> <OPTION> <SELECT>X</SELECT> <TEXT>Exit</TEXT> <COMMAND>Logout</COMMAND> </OPTION> <CURSOR>MAIN</CURSOR> </MENU>

The error that I'm receiving:

Configuration Wizard Enter a menu option to begin 1 - Configure System Administrator Password 2 - Configure Network Parameters 3 - Test TCP Network Settings 4 - Manage Processes 5 - Manage Physical Server 6 - Shell (sh) H# - Help(number) for more details X - Exit Enter your selection: MAIN> 6 \&MenuNA Undefined subroutine &main::\&MenuNA called at /home/jsmith/lib/Script +Libs/Menu.pm line 261, <> line 1.

In reply to Subroutine not being found when being called from within its own module. by curucahm

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.