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

I am trying to return all the data from this subroutine, but when I run this test code I am only getting a partial amount of data.
Is that a better way to do this? Here is the code:
#!/usr/bin/perl use strict; use warnings; use Data::Dumper; my ($test_a, $test_b, $test_c) = data(); print Dumper $test_a; print Dumper $test_b; print Dumper $test_c; my ($ar1, $ar2, $ar3); sub data { ($ar1,$ar2,$ar3) = get_data() unless $ar1; return @$ar1, @$ar2, @$ar3; }; sub get_data{ my ($ar1, $ar2, $ar3); push @$ar1, ["Acc #", "Name", "Date", "House Number",], ["1235456", "Joe More", "03/07/2010", "5",],; push @$ar2, ["", "", "","",], ["Home ", "Year", "City","",], ["", "", "","",], ["1", "2000", "Local 1","",], ["2", "2001", "Local 2 ","",], ["3", "2002", "Local 3 ","",], ["4", "2003", "Local 4 ","",], ["5", "2014", "TLocal 5 ","",], ["", "", "","",],; push @$ar3, ["", "", "","",], ["Operation:", "", "","",], ["", "", "","Name","Place", "LOC", "REF","A#1","B#2", "C#3", " +D#4",], ["", "", "","","", "", "","","", "", "",], ["", "", "","1","Mary L", "5/15/1940", "S","V","P", "-", "-",] +, ["", "", "","2","Joe T", "6/8/1990", "B","Q","X", "-", "-",], ["", "", "","3","Carl C", "07/5/1288", "A","S","Y", "-", "-",] +, ["", "", "","","", "", "","","", "", "",],; return @{ $ar1 }, @{ $ar2 }, @{ $ar3 }; }

Thanks

Replies are listed 'Best First'.
Re: Returning all data from subroutine
by tobyink (Canon) on Nov 04, 2014 at 19:39 UTC
Re: Returning all data from subroutine
by Laurent_R (Canon) on Nov 04, 2014 at 19:41 UTC
    There may be some others, but the main error is on this line:
    return @{ $ar1 }, @{ $ar2 }, @{ $ar3 };
    If you do that, all the values are flattened into a single array. You should return the array references, not the arrays:
    return ($ar1, $ar2, $ar3);
    Of course, the calling routine has to be adapted to receive array refs, not arrays. In this case I do not see the usefulness of the data subroutine (unless I missed something). But if you want to keep it, let it also return array refs.

    Basically, the whole thing could probably be rewritten as this (untested):

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my ($test_a, $test_b, $test_c) = get_data(); print Dumper $test_a; print Dumper $test_b; print Dumper $test_c; sub get_data{ my ($ar1, $ar2, $ar3); push @$ar1, ["Acc #", "Name", "Date", "House Number",], ["1235456", "Joe More", "03/07/2010", "5",],; push @$ar2, ["", "", "","",], ["Home ", "Year", "City","",], ["", "", "","",], ["1", "2000", "Local 1","",], ["2", "2001", "Local 2 ","",], ["3", "2002", "Local 3 ","",], ["4", "2003", "Local 4 ","",], ["5", "2014", "TLocal 5 ","",], ["", "", "","",],; push @$ar3, ["", "", "","",], ["Operation:", "", "","",], ["", "", "","Name","Place", "LOC", "REF","A#1","B#2", "C#3", " +D#4",], ["", "", "","","", "", "","","", "", "",], ["", "", "","1","Mary L", "5/15/1940", "S","V","P", "-", "-",] +, ["", "", "","2","Joe T", "6/8/1990", "B","Q","X", "-", "-",], ["", "", "","3","Carl C", "07/5/1288", "A","S","Y", "-", "-",] +, ["", "", "","","", "", "","","", "", "",],; return $ar1, $ar2, $ar3; }

    Update: OK, I wanted to explain too much, so that two others were faster than me by 2 minutes. ;-) Also added revised full program (untested).

      ... I wanted to explain too much ...

      When working for PerlMonks XP, the ideal strategy is similar to the one that works best when being interrogated by the police:

      1. Speak when you're spoken to;
      2. Answer the question asked without voluntering further information; and
      3. Then shut your mouth.

      Update: By "Answer the question ...", I don't mean to imply that an answer one gives to the police must necessarily be a truthful answer.

        Yeah, I guess you must be right, thanks for the advice. ;-)
Re: Returning all data from subroutine
by GotToBTru (Prior) on Nov 04, 2014 at 19:39 UTC

    Perhaps don't dereference the array refs when returning from subroutines?

    1 Peter 4:10
Re: Returning all data from subroutine
by james28909 (Deacon) on Nov 05, 2014 at 01:21 UTC
    excuse me for the idiotic comment, but i have tried to do the same as the OP and return data from a sub. like say this code for instance:
    use warnings; use strict; use diagnostics; my $string = ""; add_i_to_string($string); sub add_i_to_string { my ($string) = @_; my $new_string = $string . "i"; add_am_to_string($new_string); } sub add_am_to_string { my ($string) = @_; my $new_string = $string . " am"; add_ironman_to_string($new_string); } sub add_ironman_to_string { my ($string) = @_; my $new_string = $string . " ironman"; string_print($new_string); } sub string_print { my ($string) = @_; print $string; } #prints "i am ironman"
    now my question is, would it not be better to just pass the data to another sub for printing, or is there a specific reason we should be returning data outside of a sub instead of just passing it to another?

      Your question makes no sense. In the code you show there is no point at which you are explicitly returning data from any of your subs and at no point is implicitly returned data from any sub used. Maybe you meant something like:

      use warnings; use strict; print addIronman(addAm(addI(""))); sub addI { my ($string) = @_; $string . "i"; } sub addAm { my ($string) = @_; return $string . " am"; } sub addIronman { my ($string) = @_; return "$string ironman"; }

      Note that addI returns its result implicitly because the result is the last value evaluated before the implicit return at the end of the sub. The other subs return explicit values.

      Perl is the programming world's equivalent of English
        i was trying to reason in my post, what would be the reason for returning anything from any sub if it can be dealt with in a sub? i think that is the question i was shooting for even tho my code didnt even show it. hopefully you see what i mean tho. EDIT: very good example code tho.

      Note that GrandFather's reply (++) includes an example of what I think of as 'classic' functional programming (update: actually, I think this would more formally be called procedural programming). Open almost any introductory CS textbook (hint, hint) and you will quickly encounter further, extensive discussion of this topic.

      You are passing an argument to your subroutines, but using $string essentially as a global variable. That is defeatring the purpose of funnctions receiving arguments and returning values, which can thus be abstracted out as black boxes.