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

Hello!

Help greatly appreciated.

I have the following code:

sub extractData { my @projects; push( @projects, [readOnly("$proj Data.txt"), "A"] ); unless( $pointerProj eq "NONE" ) { push( @projects, [readOnly("$pointerProj Data.txt"), "B"] ); } for( @projects ) { my @data = @{ $_[0] }; my $key = $_[1]; ... } } sub readOnly { my @contents; my $filePath; my $file; my $errMsg; $filePath = "$path\\" . $_[0]; $errMsg = "Unable to read $filePath: $!"; open $file, '<', $filePath or die $errMsg; @contents = <$file>; close $file; return @contents; }

My problem is that I'm not correctly passing the resultant array from readOnly() through the anon array pushed in to @projects to ultimately store and use it as @data inside the for-loop.

The error message I'm getting is "Can't use an undefined value as an ARRAY reference at (the first line inside the for-loop)".

If someone could provide me with the correct syntax and the rationale behind it I would be much obliged.

Thanks!

Replies are listed 'Best First'.
Re: Passing Along Arrays
by frozenwithjoy (Priest) on Aug 26, 2014 at 20:35 UTC
    It's hard to test without having code I can run, but I changed a couple lines (marked w/ comments in the code and described more completely below) to get the functionality I think you want. Does the following work how you want it to?
    sub extractData { my @projects; push( @projects, [readOnly("$proj Data.txt"), "A"] ); unless( $pointerProj eq "NONE" ) { push( @projects, [readOnly("$pointerProj Data.txt"), "B"] ); } for( @projects ) { my @data = @{ $_->[0] }; # WAS: my @data = @{ $_[0] }; my $key = $_->[1]; # WAS: my $key = $_[1]; ... } } sub readOnly { my @contents; my $filePath; my $file; my $errMsg; $filePath = "$path\\" . $_[0]; $errMsg = "Unable to read $filePath: $!"; open $file, '<', $filePath or die $errMsg; @contents = <$file>; close $file; return \@contents; # WAS: return \@contents; }

    I changed readOnly() to return an array reference. Each project is then an array reference with another array reference (the 'data') at index 0 and a text string (the 'key') at index 1. To get these two items, you need to dereference the outer array reference with $_->[X]. You used $_[X] which is how you get an item from an array, not an array reference.

      I tried updating readOnly() to return a reference, and using -> as you indicated, but still no dice - I get the same error message.

      I realize its hard to debug without a living program so I appreciate your effort. I cannot share more than I already have.

      Previously I had readOnly() returning @contents and could store the result as follows:

      my @data = readOnly( "data.txt" );

      With readOnly() returning \@contents, how would I then store the result?

      my @data = ?

        Is this an accurate depiction of what you are attempting?

        perl -E ' use strict; use warnings; my @projects; push @projects, [ [ "the", "data" ], "key"]; push @projects, [ [ "more", "data" ], "another key"]; for (@projects) { my @data = @{ $_->[0] }; my $key = $_->[1]; say "DATA: @data"; say "KEY: $key"; } '

        OUTPUT:

        DATA: the data KEY: key DATA: more data KEY: another key

        I suggest you print (or use Data::Dumper/Data::Printer on @contents before it is returned and on $_ in the for loop to see what all is going on.

Re: Passing Along Arrays
by Laurent_R (Canon) on Aug 27, 2014 at 06:46 UTC
    Hi Perl_Ally, the code you posted is unsufficient for us to help you. You have two subs, none of which calls the other and there is no "main" code to call either of the subs. And the subs are not working on the same data. There is no way we can test, or understand, or fix, the code you presented. Please give more of the context. Please p^rovide a full program (even faulty).

      While I appreciate that a full program would be preferable, I do not see why it should be necessary to have the entire program to educate someone on how to correctly pass an array or array reference through multiple structures.

      As I work in a professional environment, I can only share snippets of code and I have to "wash" them to some extent before sharing. I appreciate that this makes assistance a more difficult task.