Search code examples
perlreferencedereference

Are all references not dereferenced the same?


I am building a program with several routines I'd like to be able to use over and over. Oh, I'm also an absolute beginner with perl, so there's that. So, I have arrays that I fill with lines of text I pull out of files so I can parse, modify, compare, etc., with either user input or other bits of data I pull from (an)other file(s) depending on the program the subroutine is deployed in.

So, I have one subroutine I pass three array references to:

@sorted = &sort_arrays(\@order, \@ktms, \@sorted);

I dereference the arrays after passing in the sub for a sanity check like so:

sub sort_arrays {
my ($ref_array, $list_array, $sorted_r) = @_;
print "@{$ref_array} \n"; print "@{$list_array} \n"; print "@{$sorted_r} \n";

and I get the values of each cell of each array printed on a single line each with a single space between them. Great! I actually had this working as an individual program to sort a random generated file from a master based on the order the random values appear in the master. Now, I am trying to make other subroutines generic and reusable with references, but I'm not having the same luck with dereferencing them. For example:

@that = &get_ktms_from_program(\@this, \@that);

But, when I try to dereference them, I get bad news!

    print "\nEntered get_lines_from_program sub\n"; 
    my ($lines_r, $parsed_r) = @_;
    print "@{$lines_r}\n";

The output:

Entered get_lines_from_program sub
ARRAY(0x81c20dc)

So, for some reason, I am unable to dereference THIS array with the same method used earlier. What gives? TIA for the help!


Solution

  • It is likely that you stored this array reference in an array somewhere. This means you now have an array with one element: an array reference. (References are how you nest data structures in Perl; see perllol). When you interpolate this array into a string, the one element (array reference) is printed, and the stringified form of an array reference looks like the string you saw. Instead, store the array reference in a scalar variable wherever you retrieve it, which can be passed to your other subroutines as-is.

    use strict;
    use warnings;
    
    my $aref = sub_returning_aref();
    other_sub($aref);
    
    sub sub_returning_aref {
      my @stuff;
      return \@stuff;
    }
    
    sub other_sub {
      my ($aref) = @_;
      print "@$aref\n";
    }
    

    The key to remember is that \@array returns a reference which is a scalar value, and can then be used as any other scalar, but must be dereferenced to yield the array contents.

    Data::Dumper is a good core tool for determining what exactly you have in a variable when debugging.

    use Data::Dumper;
    print Dumper \@array;