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

Hi Monks, I am trying to use a function in the switch statment. I am getting the error. $ perl switch_test.pl 1 Undefined subroutine &main::test_func called at switch_test.pl line 8, <STDIN> line 1. Please tell what I need to do? Do I need to use main() sommewhere?

use Switch; $i; chomp($var=<STDIN>); switch ($var){ case(1) { test_func()} } print "case: $i\n"; test_func{ print "\nhello"; }

Replies are listed 'Best First'.
Re: switch and case statement using a function
by moritz (Cardinal) on Aug 18, 2011 at 14:24 UTC
    You need to actually declare function test_func, which in Perl you do with the sub keyword:
    sub test_func { print "hello\n"; }

    See perlfunc and perlsyn for details.

    Oh, and please don't use Switch;, it can go horribly wrong, and is deprecated in favor of given/when, which are available starting from perl 5.10.0 (current old-old release).

Re: switch and case statement using a function
by osbosb (Monk) on Aug 18, 2011 at 14:24 UTC
    First, please always "use strict" and "use warnings". This will catch a lot of code problems, as you'll see with the example below and your "$i" declaration. Secondly, you try to call your test_func as a sub...without declaring it as a sub. Your code should look like this(you need to fix $i):
    #!/usr/bin/perl use strict; # always do this! use warnings; # always do this! use Switch; my $i; # we declare it, but never assign it. chomp(my $var = <STDIN>); switch ($var) { case(1) { test_func() } } print "case: $i\n"; # perl complains..$i is not assigned sub test_func { print "\nhello"; }
Re: switch and case statement using a function
by Ratazong (Monsignor) on Aug 18, 2011 at 14:24 UTC
    Have you tried to add a sub before the declaration of the test_func? Then it works fine for me...
      What is sub used for? Thanks Now it is working fine.

        The attached program code has two input params. Vendor name and Technology name. Now I am not able to access the parameter $vendor and $tech inside the sub functions like sub aln_g(). What I need to do for that. Where I need to redeclare the arguments. I am not able to read the two arguments. Also I need to pass one more argument i.e. date in YYYYMMDD format to this program. How can I make the changes for that so that the new argument is also accessible inside sub aln_g()

        #!/usr/bin/perl -w package synchronizer; use strict; use warnings; use Nexius::CM::Utils; use Getopt::Long; use Data::Dumper; use Switch; #use File::stat; #use Time::localtime; use POSIX; BEGIN { CMlog( 'info', 'Started' ); } my %month = qw( jan 01 feb 02 mar 03 apr 04 may 50 jun 06 jul 07 aug 08 sep 09 oct 10 nov 11 dec 12 ); sub main { # my ($gen_key, $host, $user, $pass, $sync, $config); my ($vendor, $tech, $help); Getopt::Long::GetOptions( # "generate_key" => \$gen_key +, # "sync" => \$sync, # "server:s" => \$host, # "user:s" => \$user, "help" => \$help, "vendor:s" => \$vendor, "tech:s" => \$tech ); if ((defined $help) || !(defined $vendor and defined $tech)) { print Dumper $0; print "Run: $0 --vendor=\"VENDOR_NAME\" --tech=\"TECHNOLOGY_NA +ME\"\n"; print "Vendor names: AlcatelLucent, Ericsson, IPAccess, Nokia, + Nortel\n"; print "Technologies: Gsm, Umts\n"; } else { switch (lc $tech) { case "gsm" { switch (lc $vendor){ case "alcatellucent" {aln_g()} case "ericsson" {eri_g()} case "ipaccess" {ipa_g()} case "nokia" {nok_g()} case "nortel" {nor_g()} else { print "The checker for $ +vendor/$tech has not been implemented.\n Try $0 --help for further in +formation"} } } case "umts" { switch (lc $vendor){ case "ericsson" {eri_u()} case "nokia" {nok_u()} else { print "The checker for $ +vendor/$tech has not been implemented.\n Try $0 --help for further in +formation" } } } else { print "The checker for $vendor/$tech has not been imp +lemented.\n Try $0 --help for further information" } } } } sub read_file { my $my_file = shift; open(FH,"< $my_file"); my @my_content = <FH>; return @my_content; } sub get_files { my ($path, $fxn_pointer_) = @_; opendir (DIR, $path) or die "Unable to open $path: $!"; my @files = grep { !/^\.{1,2}$/ } readdir (DIR); closedir (DIR); @files = map { $path . '/' . $_ } @files; for (@files) { if (-d $_) { get_files ($_, $fxn_pointer_); } else { $fxn_pointer_->( $_) } } } sub aln_g { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/alcatellucent-nss/gsm", sub{ my $my_file = shift; my @my_content = read_file($my_file); my $latest=0; foreach my $line (@my_content) { if ($line =~ m/dumped\s*\w\w\w\s*(\w\w\w)\s*(\ +d)\s*\d\d:\d\d:\d\d\s*(\d\d\d\d)/) { $latest = $3.$month{lc($1)}.sprintf("%02d" +, $2) if ($latest < $3.$month{lc($1)}.sprintf("%02d", $2)); } } $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for AlcatelLucent NSS is: $2/$3/$1\n"; } sub eri_g { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/ericsson/gsm", sub{ my $my_file = shift; my $latest = POSIX::strftime( "%Y%m%d", localtime( ( stat $my_file )[9] ) ); $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for Ericsson GSM is: $2/$3/$1\n"; } sub ipa_g { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/ip-access/gsm", sub{ my $my_file = shift; my @my_content = read_file($my_file); my $latest=0; if ($my_content[-1] =~ m/OK END/ && $my_content[-2 +] =~ m/(\d\d)(\d\d)(\d\d)/) { $latest="20$1$2$3" } $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for IP-Access is: $2/$3/$1\n"; } sub nok_g { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/nokia/gsm", sub{ my $my_file = shift; my @my_content = read_file($my_file); my $latest=0; foreach my $line (@my_content) { if ($line =~ m/\|"(\d\d)-(\d\d)-(\d\d\d\d) \d\ +d:\d\d:\d\d"\|/) { $latest = $3.$1.$2 if ($latest < $3.$1.$2) +; } } $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for Nokia GSM is: $2/$3/$1\n"; } What do you mean by "just fails"? Your code worked perfectly for me.$ perl -MPOSIX -e 'print POSIX::strftime("%d-%m-%Y %H:%M:%S", localtime) +,"\n"' sub nor_g { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/nortel/gsm", sub{ my $my_file = shift; my $latest = POSIX::strftime( "%Y%m%d", localtime( ( stat $my_file )[9] ) ); $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for Nortel GSM is: $2/$3/$1\n"; } sub eri_u { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/ericsson/umts", sub{ my $my_file = shift; my @my_content = read_file($my_file); my $latest=0; if ($my_content[-2] =~ m/<fileFooter dateTime="(\d +\d\d\d)-(\d\d)-(\d\d)T/) { $latest="$1$2$3" } $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for Ericsson UMTS is: $2/$3/$1\n"; } sub nok_u { my $date=0; get_files("$ENV{'XCONFIG_VAR_DIR'}/oss/nokia/umts", sub{ my $my_file = shift; my @my_content = read_file($my_file); my $latest=0; foreach my $line (@my_content) { if ($line =~ m/\|"(\d\d)-(\d\d)-(\d\d\d\d) \d\ +d:\d\d:\d\d"\|/) { $latest = $3.$1.$2 if ($latest < $3.$1.$2) +; } } $date = $latest if($latest && $date < $latest); } ); $date =~ /(\d\d\d\d)(\d\d)(\d\d)/; print "Latest update for Nokia UMTS is: $2/$3/$1\n"; } main; 0;
        Kindly help me out. The other switch question I have raised for this +only.