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

My applogies for not mentioning what changes i made which helped me run the script successfully. This is what i did in the subroutine to receive the arrays from the subroutine:
my ($node_ref,$error_ref)=get_node(); my @nodes=@$node_ref; my @errorlist=@$error_ref;
and here is the return statement from the subroutine get_node
return(\@serverlist, \@errorlist);
Below is the snippet of main subroutine and get_node subroutine:
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 out of ".sca +lar @nodes." in serverlist"); # clear serverlist printLog ("Truncating serverlist"); open( SRV,'>',$path.'serverlist.txt') or die "Can't open SRV '$path.serverlist': $!"; close SRV; close_log(); }
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); }
Only issue i see is ".scalar @nodes." is giving 0 value, even when i am truncating the serverlist.txt file after this print statement.

Replies are listed 'Best First'.
Re^4: Returning more than two arrays to the subroutine
by 1nickt (Canon) on Aug 18, 2015 at 18:36 UTC

    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.

      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.

      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.
Re^4: Returning more than two arrays to the subroutine
by stevieb (Canon) on Aug 19, 2015 at 02:14 UTC

    Great job. Thank you for the update.