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

Hi All, I was practicing with recursion in Perl and wrote a sub to reverse arrays of arrays of arrays... of arrays. After a little trial and error I got it working:
#!/usr/local/bin/perl use strict; use warnings; use Data::Dumper; my @array1 = (['A', 'B'], 1, 2, 3, ['One', 'Two', 'Three', ['I', 'II', + 'III'], 'Four'], 4); print Dumper (\@array1); recReverse (\@array1); print "\n===============Reversed================\n"; print Dumper (\@array1); my $count = 0; sub recReverse { my $ref2array = shift; if (ref $ref2array eq 'ARRAY') { my @newarray = reverse (@$ref2array); @$ref2array = @newarray; for my $item (@{$ref2array}) { recReverse($item); } } }
One thing I realized that there is the difference between
my @newarray = reverse (@$ref2array); @$ref2array = @newarray;
and
my @newarray = reverse (@$ref2array); $ref2array = \@newarray;
I was under the impression that both do the same thing, however I only realized that they don't. Can someone explain the difference. I mean I have seen it in action but not sure I fully understand the concept. Thanks.

Replies are listed 'Best First'.
Re: Array Reference Question
by b4swine (Pilgrim) on Sep 09, 2014 at 06:08 UTC

    The difference is shown by the following example

    use strict; use warnings; use Data::Dumper; my @x = (1,2,3); my $y; @$y = @x; $x[1] = 9; print Dumper $y; $y = \@x; $x[1] = 10; print Dumper $y;

    As you can see, in the second code, the $y is a reference to $x, so they share the same data. In the first case, the $y is a reference to an anonymous array, which has a copy of the data in $x.

    Think of the operation @a = @b. This is creating a copy of any array. That is what is happening in the first case (with @$y = @x.

    The second case is a $x = \@y, which is assigning a reference to a scalar, so there is no array copying. Only a scalar (the reference to @b) is being copied.

Re: Array Reference Question
by Laurent_R (Canon) on Sep 09, 2014 at 06:58 UTC
    @$ref2array = @newarray;
    creates a new anonymous array and a reference to it, whereas
    $ref2array = \@newarray;
    only creates a new reference to the existing array.
Re: Array Reference Question
by b4swine (Pilgrim) on Sep 09, 2014 at 06:17 UTC
    Much simpler would be
    sub recReverse { my $ref2array = shift; @$ref2array = reverse @$ref2array; for (@$ref2array) { recReverse $_ if ref $_ eq 'ARRAY' } }

    ---- edit ----

    The last code was written without any perl available. On closer look i need to do the check for an array ref before trying to reverse. A working rewrite is:

    sub recReverse { my $ref2array = shift; return unless ref $ref2array eq 'ARRAY'; @$ref2array = reverse @$ref2array; recReverse($_) for @$ref2array }

    Now I have a question. If I write recReverse $_ for @$ref2array instead of the parenthesised form of the last line, I would have thought that this was equivalent. But I get an error message:

     Can't call method "recReverse" without a package or object reference
      Yes. Very neat. Thank you. I do end up with some unnecessary and redundant code at times.
      According to perldiag
      Can't call method "%s" without a package or object reference (F) You used the syntax of a method call, but the slot filled by the object reference or package name contains an expression that returns a defined value which is neither an object reference nor a package name. Something like this will reproduce the error:
      $BADREF = 42; process $BADREF 1,2,3; $BADREF->process(1,2,3);
      I think the error message is ambiguous or somehow it expects $_ to be a reference to an object :s. From what I have read Perl is strictly a 1-time parser. It doesn't scan the file first for subs and then go and compile. In order to be able to call user methods without parentheses you have to predeclare it or define the sub first and then call it last in the file. The latter only works with non-recurisive methods. With recursive obviously you will have to predeclare it. I just tried it and it worked.

      I hope it makes sense.

      Reference:
      http://stackoverflow.com/questions/5992715/why-is-parenthesis-optional-only-after-sub-declaration
      http://perldoc.perl.org/perldiag.html