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

I would like to have the scalar values of an array ref passed to a sub modified in-place. I must pass an array ref and I must modify the values in place. As you can see, the code below works fine with two different calling conventions.
my $count = 1; sub modify { my $aref = $_[0]; ${$aref->[1]}=$count++; } sub prelayer { my $aref = shift; modify $aref; } my ($x, $mod) = (666,777); my @A = \($x, $mod); prelayer \@A; print $mod, $/; prelayer [ \$x, \$mod ]; print $mod, $/;

I was wondering if something like this would work:

prelayer([ $x, $mod ]);
if I could create some sort of special magic in the called subroutines. I would like for the calling syntax to be as clean as possible and do all the dirty work in my subroutines.

Replies are listed 'Best First'.
Re: passing an array ref to subroutine and modifying its elements
by chromatic (Archbishop) on Apr 07, 2001 at 03:59 UTC
    If you want to modify $x and $mod, your final calling convention will not work. The array reference creation syntax there actually copies the values from $x and $mod, it doesn't create references to them:
    sub change { my $arr = shift; $_++ for @$arr; } my $x = 1; my $y = 2; change([ $x, $y ]); print "($x) ($y)\n";

    If you want to modify the values themselves, you'll have to do something like:

    sub change { my $arr = shift; $$_++ for @$arr; } my $x = 1; my $y = 2; change([ \$x, \$y ]); print "($x) ($y)\n";
    which is exactly what you have. Or you could say change([ \( $x, $y ) ]);, which is my preference.
Re (tilly) 1: passing an array ref to subroutine and modifying its elements
by tilly (Archbishop) on Apr 07, 2001 at 05:33 UTC
    Looking at the way you write your functions, you clearly have not started using strict yet.

    Also why is it that you must modify the array in place? That is a design decision that I look at and wonder if there isn't a cleaner solution.

    But if you absolutely must get an argument in by reference and want to have a clean calling syntax, then I would throw out the thought that perhaps you want to make them into objects? Then at least you can localize the accesses to the internal structure in a semi-sane manner...

(tye)Re: passing an array ref to subroutine and modifying its elements
by tye (Sage) on Apr 07, 2001 at 10:23 UTC
    prelayer[\($x,$mod)]; # or sub refer { [\(@_)] } prelayer refer($x,$mod);

    Can you explain why you want such an interface? (I'm genuinely curious.)

            - tye (but my friends call me "Tye")