[comp.lang.perl] Subroutine parameters

clipper@csd.uwo.ca (Khun Yee Fung) (06/01/91)

I am using perl to write a program generator. This program has a few
recursive subroutines using more than one array passed among them.
To make sure the subroutines do not alter the content of the arrays, I
use something like:

  @arg1 = @dimen1;
  @arg2 = @dimen2;
  &traverse($level);

  .
  .
  .
  sub traverse {
    local(@dimen1) = @arg1;
    local(@dimen2) = @arg2;
    local($level) = @_;

    .
    .
    .
    @arg1 = @dimen1;
    @arg2 = @dimen2;
    &traverse($level);
    .
    .
  }

As my program is getting rather big, I am getting worried about
missing the @argn = @array part of this method, among other things. I
did get quite a lot of minor bugs because of misspelling etc.

Is there a better way of doing this? Should I use eval and pass the
names of the arrays to the subroutine and eval them to get the real
arrays and then copy them in local arrays?

Is it profitable to have a parameter list for a subroutine that will
do exactly this? Like:

  &traver($level, @dimen1, @dimen2);

  sub traverse($level1, @dimen1, @dimen2) {
    local($level2, @therest) = @_;

where we have the exact same result; $level1 is the same as $level2,
and @therest contains @dimen1 and @dimen2, just like the current perl?

I know the program I am writing is not really ideal for perl. But to
convert it to C is a very big headache as I use quite a few evals...

Thanks for any ideas.

Khun Yee
--
     Name: Khun Yee Fung                        Email: clipper@csd.uwo.ca
        Paper mail: Department of Computer Science, Middlesex College
     The University of Western Ontario, London, Ontario, N6A 5B7  CANADA

roger@mav.com (Roger Droz) (06/07/91)

In article <9105312319.AA21073@no11sun.csd.uwo.ca> clipper@csd.uwo.ca (Khun Yee Fung) writes:
> I am using perl to write a program generator. This program has a few
> recursive subroutines using more than one array passed among them.
> To make sure the subroutines do not alter the content of the arrays, I
> use something like:
> 
>   @arg1 = @dimen1;
>   @arg2 = @dimen2;
>   &traverse($level);
> 
>   .
>   .
>   .
>   sub traverse {
>     local(@dimen1) = @arg1;
>     local(@dimen2) = @arg2;
>     local($level) = @_;
> 
>     .
>     .
>     .
>     @arg1 = @dimen1;
>     @arg2 = @dimen2;
>     &traverse($level);
>     .
>     .
>   }

Perl can easily pass arrays by reference.  If I were a caller who didn't
trust the routine I was calling, I'd make a copy of the array and pass the
copy by reference:

# Pass @foo and @bar by value.
@foo_copy = @foo;
@bar_copy = @bar;
&traverse($local, *foo_copy, *bar_copy);

sub traverse {
    local($level, *dimen1, *dimen2) = @_;
    local(@arg1, @arg2);
    .
    .
    .
    @arg1 = @dimen1;
    @arg2 = @dimen2;
    &traverse($level, *arg1, *arg2);
    .
    .
}
Not much improvement because you still have to remember to make copies
of the arguments.  But after all, it is the caller that's not trusting
the called routine to the point of sacrificing performance and passing
arrays by value.

If you trust the called routine to make its own local copy before it
modifies an array, you can:

&traverse($level, *foo, *bar);

sub traverse {
    local($level, *arg1, *arg2) = @_;
    local(@dimen1) = @arg1;
    local(@dimen2) = @arg2;
    .
    .
    .
    # work with @dimen1 and @dimen2
    .
    .
    &traverse($level, *dimen1, *dimen2);
    .
    .
}

I'm posting this instead of mailing it because I'd like to see what the
real wizzards have to say on this subject.  Personally, I'm greatful for
a language where call-by-reference is the rule and call-by-value the exception.
(I don't really want to start that religion war.  I could be that I just
got used to call-by-reference from too much FORTRAN in my impressionable
years.)
____________
               Roger Droz                  Domain: roger@mav.COM           
()       ()    Maverick International      UUCP: uw-beaver!gtisqr!roger
 (_______)     Mukilteo, WA 
  (     )      
   |   |       Disclaimer: "We're all mavericks here: 
   |   |                    Each of us has our own opinions,
   (___)                    and the company has yet different ones!"