in reply to Re^2: Hash of Hash Redux
in thread Hash of Hash Redux

I am not sure what you are trying to do in terms of the algorithm but there are a few problems with your code.

Firstly, you do push(my @chroma, $genea); and push(my @chromb, $geneb); inside the scope of the while ($ranpop) { ... } loop. That means that each time around the loop you create new lexically scoped arrays to push data onto and by the time you get to the return they are out of scope so inaccessible.

Secondly, I'm not sure what you are doing with the

my $center = 1; ... while ($center--) { ... return ... ; }

That loop is meaningless as it stands because it is going to terminate early with the return and would only run the once anyway. If your $center is more than 1 it will still do the same thing as the return will always leave the subroutine. Perhaps the return should me moved to after the loop.

Thirdly, if you want to return more than one array (or hashes for that matter) from a subroutine you must return them by reference because from the caller's point of view, the three arrays you return come back as one big list. Do it something like this.

sub makeArrays { my @arrA = ( 1 .. 6 ); my @arrB = qw{ fred joe bill pete }; my @arrC = ( 1, 3, q{abc}, 8 ); return \@arrA, \@arrB, \@arrC; } my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); my @newArrA = @$refToArrA; my $elemTwoOfArrB = $refToArrB->[2];

I hope this is of use.

Cheers,

JohnGG

Replies are listed 'Best First'.
Re^4: Hash of Hash Redux
by BioNrd (Monk) on Nov 01, 2007 at 00:17 UTC
    Yes it was of pleanty of use. But tell me, am I trying to do the impossible? Here is where I am right now...without the help my comp would go out the window
    use warnings; use strict; use Data::Dumper; my $popCt = 4; my %HoH; for (1 .. $popCt) { my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); &gener(); } print Data::Dumper->Dumpxs([\%HoH], [q{*HoH}]); sub makeArrays { my ($upper, $lower); print 'Enter lower bound: '; chomp ($lower = <STDIN>); print 'Enter upper bound: '; chomp ($upper = <STDIN>); my @chroma; my @chromb; my $ranpop; $ranpop = int rand($upper - $lower + 1) + $lower; print $ranpop . "\n"; my @arrA = ( 1 .. $ranpop ); my $limiter = 50; my @holda; my @holdb; while ($ranpop) { my $genea = int rand ($limiter); push(@holda, $genea); my $geneb = int rand ($limiter); push(@holdb, $geneb); $ranpop--; } my @arrB = ( @holda ); my @arrC = ( @holdb ); return \@arrA, \@arrB, \@arrC; } sub gener { my @newind = @$refToArrA; my @newchroma = @$refToArrB; my @newchromb = @$refToArrC; for my $pop ( 1 .. $popCt ) { $HoH{$pop} = { individual => [ @newind ], chromasome1 => [ @newchroma ], chromasome2 => [ @newchromb ], }; } }
    In an ideal world I would have 4 populations with 4 different sets of individuals with 4 different sets of chromosome A and B's. At this point I feel like I am going about this all wrong...

    I know strict and warnings are returing things...but I don't know what they mean, google only helps so much.

    I really appreciate the help, but tell me if I ask the impossible.

      I know strict and warnings are returing things...but I don't know what they mean, google only helps so much.

      So in other words, you see these three messages and you don't know what they mean?

      Global symbol "$refToArrA" requires explicit package name at /tmp/junk +.pl line 53. Global symbol "$refToArrB" requires explicit package name at /tmp/junk +.pl line 54. Global symbol "$refToArrC" requires explicit package name at /tmp/junk +.pl line 55.
      You can figure out that lines 53, 54 and 55 are the first three lines after "sub gener". Now, you do have to read a bit about what "my" does in perl, so that you can figure out that in your main "for" loop (over "1 .. $popCt"), the three variables declared there with "my (...)" are not visible (are inaccessible, do not exist) outside the scope of the for loop. Those variables need to be passed to the "gener()" sub as parameters, so that the sub will have access to them, because the "gener" sub is defined outside the scope of the for loop. So do it like this:
      for ( 1 .. $popCt ) { my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); &gener( $refToArrA, $refToArrB, $refToArrC ); } # ... sub gener { my ( $refToArrA, $refToArrB, $refToArrC ) = @_; ... }
      That will get rid of the syntax errors (which were imposed because you have "use strict;" at the top). I don't know whether the script does exactly what you want, but it does run, and produces output in a coherent way.
        I fixed my issue. With a simple modification
        my ( $refToArrA, $refToArrB, $refToArrC ) = makeArrays(); $counter++; &gener( $refToArrA, $refToArrB, $refToArrC ); ... sub gener { my ( $refToArrA, $refToArrB, $refToArrC ) = @_; my @newind = @$refToArrA; my @newchroma = @$refToArrB; my @newchromb = @$refToArrC; for my $pop ( 1 .. $popCt ) { $HoH{$counter} = { individual => [ @newind ], chromasome1 => [ @newchroma ], chromasome2 => [ @newchromb ], }; } }