Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Passing a reference from a subroutine.

by Anonymous Monk
on Dec 07, 2012 at 16:20 UTC ( [id://1007775]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks!
I am trying to return this data type from the get_data(), but the "Dumper" inside of the "foreach" works (it prints all the data) but printing it outside is empty.
What is the correct way to do this, I know I am doing something wrong here:
... sub get_data { my $data = shift; my ($$one_num, $$account_num, $name, $new_name, $plano, $passdate, $ +todays_date, $descont, $firm, $value, $thetotal, $commited) ; my $c = -1; my @AoA; foreach my $infs (@{ $data->{ info } }) { $c++; $one_num = $infs->{ $one_num }, $account_num = $infs->{ $account_num }, $name = $infs->{ name }, $new_name = $infs->{ new_name } || ' ', $plano = $infs->{ plano } || ' ', $passdate = $infs->{ passdate }, $todays_date = $infs->{ todays_date }, $descont = $infs->{ descont }, $firm = $infs->{ firm }, $value = $infs->{ value }, $thetotal = $infs->{ premium }, $commited = $infs->{ commited }; push @{ $AoA[$c] },$$one_num, $$account_num, $name, $new_name, $pl +ano, $passdate, $todays_date, $descont, $firm, $value, $thetotal, $co +mmited; } #print Dumper \@AoA; return @\@AoA; } my $alldata= get_data(); print Dumper $alldata; ...

Thanks or the Help!

Replies are listed 'Best First'.
Re: Passing a reference from a subroutine.
by roboticus (Chancellor) on Dec 07, 2012 at 16:23 UTC

    Try changing:

    return @\@AoA;

    to

    return \@AoA;

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Sorry, that was a typo, and even with "return \@AoA;" it still doesn’t work.

        The syntax is clearly correct (as shown in the example below). So if you're getting the proper data with Dumper in your for loop, then you're likely damaging the data between the Dumper call and your return statement.

        $ cat t.pl #!/usr/bin/perl use strict; use warnings; sub get_data { my $data = shift; my @AoA = (1 .. $data); return \@AoA; } my $aref = get_data(5); print join(", ", @$aref), "\n"; marco@Boink:/Work/Perl/Sudoku $ perl t.pl 1, 2, 3, 4, 5

        ...roboticus

        When your only tool is a hammer, all problems look like your thumb.

Re: Passing a reference from a subroutine.
by toolic (Bishop) on Dec 07, 2012 at 16:42 UTC
    This works:
    use warnings; use strict; use Data::Dumper; sub get_data { my @AoA; @AoA = ( [(1, 2)], [(3, 4)], ); #print Dumper(\@AoA); return \@AoA; } my $alldata = get_data(); print Dumper($alldata); __END__ $VAR1 = [ [ 1, 2 ], [ 3, 4 ] ];
Re: Passing a reference from a subroutine.
by Lotus1 (Vicar) on Dec 07, 2012 at 19:23 UTC

    When you call the sub like this my $alldata= get_data(); you aren't passing anything to the subroutine. There is no data for it to get.

    When you do this $one_num = $infs->{ $one_num }, where was the value for $one_num initialized? It doesn't look like it was initialized to anything so the value inside the brackets is going to be undef. Are you using warnings? Strict?

    my $c = -1; ... foreach my $infs (@{ $data->{ info } }) { $c++; ... push @{ $AoA[$c] },

    A more Perlish way to do this is to push each value into a temporary array inside the loop and then push that array into @AoA at the end of each itteration. This would drop out all the loop variables and simplify the notation.

      Like this?
      ... my @temp_array; push @temp_array, $one_num, $$account_num, $name, $new_name, $plano, $ +passdate, $todays_date, $descont, $firm, $value, $thetotal, $commited +; push @{ $AoA[$c] }, @temp_array; } return @AoA; }
Re: Passing a reference from a subroutine.
by GrandFather (Saint) on Dec 08, 2012 at 06:53 UTC

    Inventing rubbish then asking us to tell you why it isn't working doesn't help you and doesn't do much for us either. There are at least four "That ain't possibly right" issues with the code you have shown and the story you tell about it. How about you copy and paste a small code sample that actually demonstrates the error you see? Show us the output too!

    True laziness is hard work
Re: Passing a reference from a subroutine.
by blue_cowdawg (Monsignor) on Dec 07, 2012 at 16:39 UTC

    return [ @AoA ];


    Peter L. Berghold -- Unix Professional
    Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg
Re: Passing a reference from a subroutine.
by muba (Priest) on Dec 13, 2012 at 04:10 UTC

    Wow. Just... wow

    My brain exploded several times while reading your code. First of all, there was the suboptimal indentations (just two spaces? Really?), next there was this long, long list of variable assignments some of which seem to have some sort of default fallback value, whereas others don't. But as a whole, it certainly wasn't easy on the eyes. So I copy/pasted your code into my favourite editor to make it more readable.

    I stumbled across my $data = shift; — so I made a mental note to remember $data - it bears special meaning, because it will hold the argument given to this subroutine.

    Then I saw this immensely long list of variable declarations and my brain just stopped right there. "No," it said. "I ain't gonna do this. I ain't even pretending I'm able to keep track of so many variables at once."

    "Calm down," I said, "how bad can it be? We've done worse, brainy-brain."

    "No," my brain said, sobbing, "look at it. my $$one_num? What the h*** does that even mean? Are we dereferencing a variable that don't even exists yet? And... the naming convention, is there even one? $new_name and $todays_date, but $passdate and $thetotal? It's a mess, dude. A mess. Seriously, I ain't not doing it." Then it made some sort of defensive, hands-off kind of gesture and turned its back at me. I think it was serious about not wanting to do it.

    But I had to say my brain was having a point there. Anyway, I read a little more of your code, and, curious as it is, my brain peeked along, and I swear I could feel it shed a tear when we noticed each and every one of those assignment statements (except for the last one) ended in a comma. Why? What does it signify? How does it even work? What would've been wrong with semicolons in those places? Why is there this long list of my (...) near the top of this subroutine that doesn't even word-wrap prettily while you could've just gone my $one_num = $infs->{ $one_num }; ... Wait ... what?

    My brain was loud when it vocalized its next protest. "Where the h*** does that last $one_num even come from? The one inside the curly braces? The only thing we've assigned so far is $data! There ain't no $one_num! And look! Just look, dude! He does it again in the next line, with $infs->{$account_num}. There ain't no $account_num! It holds no value that I know of!" It looked at me, desperately, and stated ever so clearly, "Ain't. Gonna. Do it."

    It added a dramatic silence, before it elaborated, "$one_num and $account_num? They're like the magician's rabbits, coming out of this hat and everything. Look, a rabbit is there, or it ain't there. There ain't no such thing as a rabbit not being in a hat, yet still coming out of that hat."

    Still, I continued, reading, and basically what I extracted was that you're trying to build an array out of certain elements that you took from the hash ref $infs. You do this by pushing onto @AoA... What?

    Where does @AoA even come from? Another rabbit? Oh, wait, no. It's hidden near the top, right there on the line my $c = -1; my @AoA;. I see what you did there — sleigh of hand. While you're amazing your audience with pulling rabbits with one hand, your other hand sneakily tries to hide a variable behind another one. Really clever. Good move, too, to throw us of our tracks, but I caught you, haha!

    Still, I had my hopes up that I would be able to make it more readable, even though I wasn't sure what I would do about these $one_num and $account_num rabbits. I decided to leave them for what they were for now, as is, and deal with them later, and this is what I came up with.

    # Code readability improvement - phase 1 sub get_data { my $data = shift; my $c = -1; my @AoA; foreach my $infs ( @{$data->{ info }} ) { $c++; my $one_num = $infs->{ $one_num }; my $account_num = $infs->{ $account_num }; my $name = $infs->{ name }; my $new_name = $infs->{ new_name } || ' '; my $plano = $infs->{ plano } || ' '; my $passdate = $infs->{ passdate }; my $todays_date = $infs->{ todays_date }; my $descont = $infs->{ descont }; my $firm = $infs->{ firm }; my $value = $infs->{ value }; my $thetotal = $infs->{ premium }; my $commited = $infs->{ commited }; push @{ $AoA[$c] },$$one_num, $$account_num, $name, $new_name, + $plano, $passdate, $todays_date, $descont, $firm, $value, $thetotal, + $commited; } #print Dumper \@AoA; return \@AoA; } my $alldata= get_data(); print Dumper $alldata;

    "Oh," said my brain, "it's starting to look like something. Still, this seems like a whole lot of lines for something incredibly simple, don'tcha think? Look, there's something there called $value &mdash as opposed to what? The rest of those variables don't represent certain values? And I don't like none of that push ... line none. It's painful to watch, buddy."

    "Hm hm," I murmered, as I silently pointed at the my $alldata= get_data() line, especially the part between the parens, where no arguments were given, even though we had taken a mental note to remember the $data variable which would hold the argument given to the subroutine. "I'll show you 'painful'," I thought to my brain, which, being my brain, is able to tell what I'm thinking without me having to tell it what I'm thinking. Which, I think, is quite awesome.

    It hurt when I felt how my brain was fighting the urge to just go with its internal Error/Reset/Retry routine. "All this pain to do all that... stuff... that we just had to read through... with NOTHING?" It cried. I tried to comfort it, but it began to tell a little anecdote. "It's like when you were a kid and had to do chores for the whole village for two weeks so you could have five dollars so you could go to the circus, and you had to get there by walking uphill for three hours with the wind blowing in your face. And rain. Oh yeah, lots of cold harsh rain smashing against the soft tender flesh of your face, turning your skin raw and burning. But at last you arrive! And you know what happens then?"

    "What happens then?" I asked, dreading I already knew the answer, because wasn't my brain just recalling one of my own memories?

    "There ain't no circus. There never ever even been no circus." It sighed. "Seriously. Next time I say I ain't it, you oughta listen."

    But we had come so far, I felt we could at least just try to turn this mess into something that at least made a little sense, so I came up with the following:

    # Code readability improvement - phase 2 sub get_data { my $data = shift; my @AoA; my @keys_that_I_care_about = qw( one_num account_num name new_name plano passdate todays_date descont firm value thetotal commited ); my @keys_that_need_a_default_value = qw( new_name plano ); my $default_value = " "; foreach my $infs ( @{$data->{ info }} ) { my %infs_copy; $infs_copy{$_} = $infs->{$_} for @keys_that_I_care_abou +t; $infs_copy{$_} = $default_value for @keys_that_need_a_defa +ult_value; push @AoA, [ @infs_copy{@keys_that_I_care_about} ]; } #print Dumper \@AoA; return \@AoA; } my $alldata= get_data(); print Dumper $alldata;

    "Wow," said my brain, "is this essentially the same code?"

    I nodded, "yes. Except I've taken out those $one_num and $account_num rabbits. I hope they were meant as key names anyway instead of variables. But if they weren't, then I'm still gonna pretend they were, for my own sanity."

    "Yeah," said my brain. "This is something that looks remotely mentally parse-able."

    "Hm hm," I murmured. Not wanting to send my brain to its personal hell again, I resisted the urge to point at the line that called the subroutine with no arguments. It certainly looked better now, but it still wasn't doing a darn thing.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1007775]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others perusing the Monastery: (6)
As of 2024-03-19 09:21 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found