in reply to Re^3: Returning more than two arrays to the subroutine
in thread Returning more than two arrays to the subroutine

What does @nodes contain right before you call scalar() on it? You don't check in main() to see whether or not it is empty. Do enable_unplanned_outage() and disable_unplanned_outage() check to see whether there is anything in the array they are passed?

Also, if you just get an arrayref from get_node and only use it to pass it on to other subs (besides your print warning), why dereference it? You might as well pass the arrayref to the next sub and only dereference it when you need to use it.

The way forward always starts with a minimal test.

Replies are listed 'Best First'.
Re^5: Returning more than two arrays to the subroutine
by Monk::Thomas (Friar) on Aug 18, 2015 at 21:17 UTC

    Also, if you just get an arrayref from get_node and only use it to pass it on to other subs (besides your print warning), why dereference it?

    I can't speak for shroh, but I would derefence it anyway because I'm paranoid and want to avoid any chance of some function messing around with the content of the array. Even if I wrote the function myself - accidents happen. (I reserve passing a reference for cases where I do want to modify it or where copying the array has a noticeable impact on performance.)

    Maybe one could

    use Readonly; ... Readonly my @result => do_some_computation(); do_something(\@result); do_something_else(\@result);

    but I haven't yet had a need to test out if this would really work as expected in all circumstances.

Re^5: Returning more than two arrays to the subroutine
by shroh (Acolyte) on Aug 18, 2015 at 18:59 UTC
    The @nodes contain the array of servers which i am passing to the other subs. Even in other subs(enable_unplanned_outage() , disable_unplanned_outage() i am able to use the same array without any issues. When i do a scaler on @errorlist i am able to get the exact number of elements in that array.

      OK. You haven't shown the other subs so I can't comment on what's happening there. But you said:

      When i do a scaler on @errorlist i am able to get the exact number of elements in that array

      So why do you not believe scalar() with @nodes? Do you not think that perhaps it is telling the truth and the array is empty?

      Again, what is in @nodes right before you call scalar() on it?

      use Data::Dumper; print Dumper \@nodes;

      I can see that you check whether the array returned by reading the file is empty, and exit if so, but then you pass that data to getNodeAttributes() (not shown), and from that point on you don't test what you have before calling scalar @nodes.

      The way forward always starts with a minimal test.
        Hi , Please find the complete code
        #!C:\Perl\bin\perl.exe use strict; use warnings; #use diagnostics; # This script is leveraged by an OMW tool and is used to [enable | d +isable] unplanned outage # mode on a list of servers. It requires two arguments [action] and + [filename]. #===================================================================== +========================== &main(); sub main { my $path = 'E:/scripts/OutageNodes/'; require $path.'omwNodeDetails.pm'; open_log($path.'maintenanceMode_'); my $mode=get_mode(); my ($node_ref,$error_ref)=get_node(); my @nodes=@$node_ref; my @errorlist=@$error_ref; if( $mode eq 'enable'){ enable_unplanned_outage(@nodes); } elsif($mode eq 'disable'){ disable_unplanned_outage(@nodes); } else { printLog("Error invalid Mode $mode"); } printLog("There were ".scalar @errorlist." failed servers in serverlis +t"); # clear serverlist printLog ("Truncating serverlist"); open( SRV,'>',$path.'serverlist.txt') or die "Can't open SRV '$path.serverlist': $!"; close SRV; close_log(); } sub get_mode { # expect values 'enable|disable' my $maintMode = lc $ARGV[0]; chomp($maintMode); if ($maintMode ne 'enable' && $maintMode ne 'disable'){ $maintMode="error"; } return $maintMode; } sub get_node { my @errorlist=(); my $sPath='e:/scripts/OutageNodes/'; my $sInFile=$sPath.'serverlist.txt'; my @sContent=(); my $sText; ##checks if the file exists and pulls the info out if (-e $sInFile){ open INFILE, '<', $sInFile or die "Could not open $sInFile : $!"; while (<INFILE>){ chomp; $sText="$_"; push @sContent,$sText; } close INFILE; } else { printLog("ERROR Cannot open $sInFile"); } # check serverlist had entries if (@sContent == 0){ printLog("ERROR No nodes found in serverlist.txt"); close_log(); exit; } #get FQDN************ my $hostname; my $fqdn; my @serverlist; for my $NODE (@sContent){ ($hostname) = split /\./, $NODE; $fqdn = getNodeAttributes($hostname,'PrimaryNodeName'); if(length($fqdn) < 1) { printLog("No value returned from WMI, node ($NODE) doesn't ex +ists in OMW."); push @errorlist,$fqdn; next; } else { push(@serverlist,$fqdn); } } return(\@serverlist, \@errorlist); } sub enable_unplanned_outage { my @nodelist=@_[0..$#_]; foreach my $FQDN (@nodelist) { printLog ("===================\n Putting the server $FQDN into outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_he +artbeat -delete_msgs -node_name $FQDN -on "; my $output =`$cmd`; `$cmd`; printLog($output); } } sub disable_unplanned_outage { my @sContent = @_[0..$#_]; ####When the servers is brought out of maintenance the agent has to be + recycled to reset all the monitors. foreach my $FQDN (@sContent) { printLog ("===================\n Bringing the server $FQDN out of outage."); my $cmd = "ovownodeutil.cmd -outage_node -unplanned -disable_ +heartbeat -delete_msgs -node_name $FQDN -off "; `$cmd`; my $output=`$cmd`; printLog($output); printLog("Restarting the opcmona to reset the monitors"); my $cmdresopcmona = "ovdeploy -cmd \"ovc -restart opcmona\" - +host $FQDN"; `$cmdresopcmona`; } } sub printLog { my ($logLine) = @_; my $time = sprintf "%02d:%02d:%02d",(localtime)[2,1,0]; my $date = sprintf "%04d%02d%02d",$year + 1900 , $month + 1 , $day ; my $now=$date"\t"$time; print LOG "$now $logLine\n"; } sub open_log { my ($filename) = @_; my ($day,$month,$year) = (localtime) [3..5]; #my $date = sprintf "%04d%02d%02d",$year + 1900 , $month + 1 , $day +; my $logfile = $filename.'.log'; open LOG,'>>',$logfile or die "Can't open LOG '$logfile': $!\n"; print LOG "\n====SCRIPT START====\n"; } sub close_log { print LOG "====SCRIPT END====\n"; close LOG; }