On 9/13/07, Tim McGeary <[EMAIL PROTECTED]> wrote:

> I am trying to use a 3-dimensional array:
> [fileset][record][line]

I think you're telling us that the first dimension tells which fileset
something is or was found in, the second tells which record within
that fileset, and the third tells which line in the record. Okay....

> I think that I am reading and pushing the arrays onto the other arrays
> correctly, but when I'm traversing the arrays to do the conditionals, I
> am getting uninitialized value warnings, which seems like I'm either not
> traversing correctly OR I'm not really pushing the data onto the arrays
> properly.

Have you used a module such as Data::Dumper to see what your data
structure looks like? Or, my preferred technique, you could use the
debugger: Set a breakpoint for the right place, then use the x command
to see the structure. If the structure will take more than a screenful
to dump (i.e., nearly all real-world structures) you can use the pipe
option to view it through your pager program. The command at the
debugger prompt might look like this, if I wanted to see what
structure was in @proquest:

      DB<7> |x [EMAIL PROTECTED]

> This is my whole script below.  Does anyone see what I'm doing wrong?

Thanks for sending your real code!

> use strict;
> use warnings;

Good....

>        else {
>           @line = ();
>           my $field = substr($_, 0, 5);
>           my $data = substr($_, 5);
>           push @line, [ $field, $data ];

This raises a warning flag in my mind. You're using push correctly,
but that same target array variable was just wiped out a few lines
earlier. Is that correct? If you're hoping to ever have more than a
single item in @line at a time, you'll have to add more data; and I
can't see where you're doing that. (It could still be correct, if you
know that there will always be either one item in @line, or none.)
Maybe the line erasing @line needs to be moved to a different place in
the algorithm.

> my $pdiss_id;
> my $s001;
> my $sdiss_id;
> my $found;
>
> my $p;
> my $pl;
> my $s;
> my $sl;

This gives another warning flag. It's not necessarily bad style, but
it's not my style. I prefer to declare each variable as it's first
needed, instead of all at the top. But if I do need to declare many
my() variables at once, I put them together:

  my($pdiss_id, $s001, $sdiss_id, $found, $p, $pl, $s, $sl);

Also, I hope that names like $s001 and $sl are meaningful to you. As a
general rule (and a point of style) I use short variables names like
$p only in short sections of code, such as inside a loop or sub which
fits completely on-screen. When a variable needs to be used over a
large enough span of code that I can't easily see all of its uses at
once, it needs a more self-descriptive name, like $response. (And the
exception is when the variable is so "famous" that $s is all it needs
to go by.)

> for $p ( 0 .. $#proquest ) {

Again, valid; but a warning flag. Do you need to iterate through
indices, or can you use the elements themselves? The question comes
into my head before I even look at the rest of your code. Sometimes
you do need the indices, but often this is a sign that you're not
"thinking in Perl" quite enough to use foreach, and deal with elements
instead of indices:

  foreach my $elem (@proquest) { ... }

>        if ($proquest[$p][$pl][0] eq '.001.') {
>           $pdiss_id = substr($proquest[$p][$pl][1], 6, 7);

Here, when you find the right element 0, you immediately use element
1. Could this be where you're running out of array elements? Could
this be the same data we saw earlier, that was (inadvertently?)
limited to a maximum of one element?

If you're still having troubles, you'll probably see what's going on
if you can step through your program in the debugger, checking on the
key variables as you go. Good luck with it!

--Tom Phoenix
Stonehenge Perl Training

-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to