How to pass two arrays to another subroutine in Perl

Tolgar
Tolgar used Ask the Experts™
on
How can I pass two arrays to another subroutine?

Example:

my ($result, @failedLineBits) = &helperFunctions::markFailedLines(@line_numbers,@data);

Open in new window


package helperFunctions;		
		
use strict;
use warnings;

sub markFailedLines{
my (@line_numbers, @data) = @_;

SOME CODE IN HERE

return ($result,@out);
}
1;

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
combine the two arrays into a single array using "push"

example:

@time = ("hour","minutes");
@date =("day","year");
Push (@time, @date);

Once you have the single array, pass the single array to the sub.
ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015
Commented:
Pass the arrays as references:

my ($result, @failedLineBits) = &helperFunctions::markFailedLines(\@line_numbers,\@data);

Open in new window


sub markFailedLines{
    my ($line_numbers, $data) = @_;

    print @{$line_numbers};
    print @{$data};

    return ($result,@out);
}

Open in new window


http://www.cs.cf.ac.uk/Dave/PERL/node61.html

Author

Commented:
@kaufmed: Ok. I tried your solution and I am getting "Global symbol "@data" requires explicit package name" error.

Here is my whole function:

sub markFailedLines{
my ($line_numbers, $data) = @_;
my @out;
	if ($line_numbers) {
		foreach my $ln ($line_numbers) {
			$data[$ln+2] = "<font color=\"red\">$data[$ln+2]</font>";
			push(@out, '<br><br>');
			push @out, join('<br>', map{ join(': ', $_, $data[$_+2]) } $ln-3..$ln+3);
		}
		return ('FAILED',@out);
	} else {
		return ('PASSED',@out);
	}
}

Open in new window


What am I doing wrong here?
CompTIA Security+

Learn the essential functions of CompTIA Security+, which establishes the core knowledge required of any cybersecurity role and leads professionals into intermediate-level cybersecurity jobs.

ǩa̹̼͍̓̂ͪͤͭ̓u͈̳̟͕̬ͩ͂̌͌̾̀ͪf̭̤͉̅̋͛͂̓͛̈m̩̘̱̃e͙̳͊̑̂ͦ̌ͯ̚d͋̋ͧ̑ͯ͛̉Glanced up at my screen and thought I had coded the Matrix...  Turns out, I just fell asleep on the keyboard.
Most Valuable Expert 2011
Top Expert 2015

Commented:
Do you have any code above sub markFailedLines?
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
my ($line_numbers, @data) = @_;
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
foreach my $ln ($line_numbers) {
There's no reason for such a loop over a single element

Author

Commented:
@Ozo: $line_numbers is a reference to an array. It has more than one value in it.
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
markFailedLines(\@line_numbers,\@data);
sub markFailedLines{
my @line_numbers = @{+shift};
my @data = @{+shift};
foreach my $ln (@line_numbers) {

Author

Commented:
@kuafmed: Yes there is another sub function. But the error is for the lines 6 and 8 in the above code.

Author

Commented:
@Ozo: Why do I need to use shift? I don't find it very secure to use.
 Is there a way of modifying my code above without using shift?
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
$line_numbers is a reference to an array. It has more than one value in it.
It is a single reference.
 foreach my $ln ($line_numbers) {
would alias $ln to the single reference
 foreach my $ln (@$line_numbers) {
would alias $ln to each of the elements in the referenced array

Author

Commented:
@Ozo: I am confused. Can you please send me the modified version of my code above?
Most Valuable Expert 2014
Top Expert 2015
Commented:
Using references
                        $data->[$ln+2] = "<font color=\"red\">$data->[$ln+2]</font>";
                  push(@out, '<br><br>');
                  push @out, join('<br>',map{ join(': ', $_, $data->[$_+2]) } $ln-3..$ln+3);
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
If $line_numbers is always reference,
if ($line_numbers) {
will always be true
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
#If you call
markFailedLines(\@line_numbers,\@data);
#then you can use
sub markFailedLines{
my ($line_numbers, $data) = @_;
my @out;
            foreach my $ln (@$line_numbers) {
                  $data->[$ln+2] = "<font color=\"red\">$data->[$ln+2]</font>";   #note that this modifies the original @data
                  push @out, '<br><br>',join('<br>', map{ join(': ', $_, $data->[$_+2]) } $ln-3..$ln+3);
            }
            return @out?'PASSED':'FAILED',@out;  #this will pass when @line_numbers is not empty
}
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
#If you want to pass a copy of @data to prevent the sub from modifying the original, you can call
markFailedLines(\@line_numbers,[@data]);
ozo
Most Valuable Expert 2014
Top Expert 2015

Commented:
#Or you can pass only the first array as a reference:
markFailedLines(\@line_numbers,@data);

sub markFailedLines{
my ($line_numbers, @data) = @_;
my @out;
            foreach my $ln (@$line_numbers) {
                  $data[$ln+2] = "<font color=\"red\">$data[$ln+2]</font>";  
                  push @out, '<br><br>',join('<br>', map{ join(': ', $_, $data[$_+2]) } $ln-3..$ln+3);
            }
            return @out?'PASSED':'FAILED',@out;
}

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial