Re: arrays of arrays question

From: Jim Gibson (jgibson_at_mail.arc.nasa.gov)
Date: 10/25/04


Date: Mon, 25 Oct 2004 12:05:15 -0700

In article <1098716627.269712@nntp.acecape.com>, daniel kaplan
<nospam@nospam.com> wrote:

>
> my code essentially was to run a MySQL query, then put all the found records
> in ONE array.
>
> so originally i did this:
>
> while (@row = $sth ->fetchrow_array)
> push @rows, \@row;
>

You have a scoping problem here. @row is a global array, and at each
iteration through the loop you are fetching values into @row, then
storing a reference to @row in the @rows array. Unfortunately, all of
the references you are storing are to the same array, the one global
array @row. Also, each assignment to @row with the return values from
the call to fetchrow_array overwrites the previous values in @row. The
last call to fetchrow_array returns a null array, and that is what is
in @row when the loop exits. Therefore, at the end of the loop, you
have many array references in @rows all pointing to the same, empty
array.

Replace the loop by:

   while( my @row = $sth->fetchrow_array ) {
      push @rows, \@row;
   }

Then, each iteration through the loop creates a new, temporary array
@row, and a reference to each of these distinct arrays will be added to
@rows. The reference to each of the temporary arrays in @rows ensures
that the temporary arrays will be kept around as long as @rows exists
and does not go out of scope.

> my thinking was that this give me an array of references to all found
> records, for me to access later. somewhere this went wrong and i couldn't
> pull anything out. i was under the impression from my reading that somehow
> perl keeps the references even after you leave a subroutine that created the
> reference. which is so beyond me i have to keep re-reading that chapter,
> because i am so used to having to treat references (pointers in C) under
> much stricter rules.

Perl has similar scoping rules for references as C has for pointers.
References/pointers are scalars that can have a file scope (globals) or
a block scope ('my' variables) (ignore package variables for now). It
is the thing the reference/pointer points to that is different. In C,
the referent may go out of scope and the memory reused, even though the
pointer still points to it. In Perl, the referent will be kept around
until the reference variable goes out of scope or is changed so it no
longer refers to the referent and there is no other reference variable
pointing at the same referent.

>
> so that didn't work, i don't recall the exact problem i ran into, my
> solution was this:
>
> while (@row = $sth ->fetchrow_array)
> push @rows, [@row];

This works because [@row] creates a new, anonymous array that is a copy
of @row and returns a reference to it, which is then pushed onto @rows.
However, you can avoid the unnecessary copying by using the modified
loop shown above.
>
> which i was then able to get each item i needed with
>
> $rows[x]->[y]
>

When you get into trouble like this, start printing out things like the
values returned by fetchrow_array in each iteration or the array
reference values. You can use the Data::Dumper module to print complex
data structures easily. If you had 'use strict' at the beginning of
your program, Perl would have complained about global variables without
an explicit package name. Posting a complete, working program would
also have let people point out the problem much sooner.



Relevant Pages

  • Re: VB-101: Passing Arrays ByVal vs ByRef
    ... changed if an array is passed by Val. ... ' new reference ... As each function creates a new array object, ... 'secondArray' and 'secondArrayCopy'. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: Need help with textboxes
    ... The JavaScript 1.5 Reference already states: ... All forms and their children are stored in an array ... use dot notation or object literals. ... No. Bracket property accessors allow their argument to be any string value. ...
    (comp.lang.javascript)
  • Re: HashTables and scoping
    ... the hashtable holds a reference to the object in the array. ... goes out of scope, as long as the hashtable is in scope, then the references ... > I've got a Class1[] that I'm wanting to load into a hash table, so, I> basically run through a loop and do a ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Garbage Collection Issues in long-standing services
    ... the pinned array should get unpinned or ... The receive case is done quite well, I do create a 4K buffer and reuse it ... and remove the reference to my wrapper socket class, ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: How to give selective access to the methods in a class?
    ... different memory locations at different times. ... The reference still leads to the ... So array resizing ... program pushes certain objects into the circular buffer, ...
    (comp.lang.java.programmer)