How to pass a copy of a matrix to a subroutine? 
Author Message
 How to pass a copy of a matrix to a subroutine?

Greetings, perl experts!


        $matrix[1][1] = "a"
        $matrix[1][2] = "b"
        ....
        $matrix[4][4] = "r"

  if I pass it to a subroutine


  with $test being defined as

  sub test {

  and do any modifications (i.e.)

        $new[1][1] = "z"


passing by reference.  :(

  How do I pass / modify a local copy and leave the original alone?

  Many thanks!



Sat, 23 Aug 2003 00:59:59 GMT  
 How to pass a copy of a matrix to a subroutine?

Quote:

>    $matrix[1][1] = "a"

[snip]

Quote:
>   and do any modifications (i.e.)

>    $new[1][1] = "z"


>passing by reference.  :(

>   How do I pass / modify a local copy and leave the original alone?



Or, just pass in the copy ref, and deref within your subroutine:


# or

   &test ($matrix_copy_ref);

   sub test {

# or
     my $matref = shift;
     $matref->[1][1] = 'z';
# or even
     $_[0]->[1][1] = 'z';  # no previous shift!

As long as you work from a [] copy reference, your original is safe.

HTH

1;

--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Sat, 23 Aug 2003 02:01:27 GMT  
 How to pass a copy of a matrix to a subroutine?

Quote:


>         $matrix[1][1] = "a"
>         $matrix[1][2] = "b"
>         ....
>         $matrix[4][4] = "r"

> if I pass it to a subroutine


> with $test being defined as

>   sub test {

> and do any modifications (i.e.)

>         $new[1][1] = "z"


> passing by reference.  :(

Not really. Remember that Perl doesn't actually have multidimensional

a one-dimensional array of references to a whole bunch of other anonymous
arrays. An access to an individual element should really be written
"$matrix[1]->[4]", but Perl allows the syntactical shorthand of
dropping the "->" between any two array or hash indices.



original anonymous arrays, so any changes made in &test() show up in
them.


need to do something like this:



from its contents.

-- Dave Tweed



Sat, 23 Aug 2003 01:45:36 GMT  
 How to pass a copy of a matrix to a subroutine?

Quote:
> Greetings, perl experts!


> $matrix[1][1] = "a"
> $matrix[1][2] = "b"
> ....
> $matrix[4][4] = "r"

>   if I pass it to a subroutine


>   with $test being defined as

>   sub test {

>   and do any modifications (i.e.)

> $new[1][1] = "z"


> passing by reference.  :(

No! Actually you're passing a list of references to arrays. It's
like if you're doing:



    ...


On the sub, you have the equivalent of



if you change $new[1][1], you're actually changing $matrix_1[1],


isn't changed at all!

Quote:
>   How do I pass / modify a local copy and leave the original alone?

You should probably do a deep copy of the array inside the sub.
You can probably do it very easily with map, or (if you don't
like map) foreach should do it too.

You should also check perldoc on the topics of LoL (list of list),
that deals with the issue of using bi-dimensional matrices (among
other nested structures), and also look at perlfunc for map.

Hope you can find your way from here!

Quote:
>   Many thanks!

You're welcome! I hope I could help.

- Branden



Sat, 23 Aug 2003 02:19:31 GMT  
 How to pass a copy of a matrix to a subroutine?

[snip]

Quote:
># or even
>     $_[0]->[1][1] = 'z';  # no previous shift!

>As long as you work from a [] copy reference, your original is safe.

But pay attention to what Dave Tweed just posted, especially

Quote:

>a one-dimensional array of references to a whole bunch of other anonymous
>arrays. An access to an individual element should really be written
>"$matrix[1]->[4]", but Perl allows the syntactical shorthand of
>dropping the "->" between any two array or hash indices.


>original anonymous arrays, so any changes made in &test() show up in
>them.

My examples should be corrected to take your changes per Dave,
assuming you keep the data structure you had in mind. Perhaps the
larger topic here, use of refs for data structures, needs some
attention. The latest edition of the Camel (Programming Perl, by
Wall, Christiansen and Orwant, O'Reilly) has a good explanation, as
long you follow this caution: try it in little steps; don't read the
whole chapter and then immediately try to do the most complex things
discussed at the end, enticing as they may be.

1;
--

   - Bruce

__bruce_van_allen__santa_cruz_ca__



Sat, 23 Aug 2003 02:31:53 GMT  
 How to pass a copy of a matrix to a subroutine?


:   if I pass it to a subroutine
:

:
:   with $test being defined as
:
:   sub test {

:
:   and do any modifications (i.e.)
:
:       $new[1][1] = "z"
:

: passing by reference.  :(

Not exactly, but other posters have corrected you on this.  You need

    sub copy_matrix {
        my $orig = shift;



    }

The Storable module (available on the CPAN) has a subroutine named
dclone for creating deep copies of arbitrary datastructures.  The author
of the Storable module, Raphael Manfredi, makes this note about dclone:

    There is a new Clone module available on CPAN which implements deep
    cloning natively, i.e. without freezing to memory and thawing the
    result.  It is aimed to replace Storable's dclone() some day.
    However, it does not currently support Storable hooks to redefine
    the way deep cloning is performed.

Hope this helps,
Greg
--
I went to a bookstore and asked the saleswoman, "Where's the self-help
section?"; She said if she told me, it would defeat the purpose.
    -- George Carlin



Sat, 23 Aug 2003 03:12:49 GMT  
 How to pass a copy of a matrix to a subroutine?

Quote:


> passing by reference.  :(

Yes, in effect.

Quote:
>   How do I pass / modify a local copy and leave the original alone?

The short answer is, you need to make a "deep copy" of the original
data structure.  There are modules on CPAN for this.

--
John Porter

Useless use of time in void context.



Sat, 23 Aug 2003 03:15:56 GMT  
 How to pass a copy of a matrix to a subroutine?
[A complimentary Cc of this posting was sent to Bruce Van Allen


Quote:
> >       $matrix[1][1] = "a"

To get poorer performance, but easier passing-by-reference (when
needed), make it

  $matrix->[1][1] = "a";

Quote:
> >   How do I pass / modify a local copy and leave the original alone?




I think these are deeper copies, but not deep enough.


Hope this helps,
Ilya



Sat, 23 Aug 2003 15:28:21 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Run Minimized

2. Looking for wincrt.tpu or .pas

3. Please Advise. Strange Math Results. Is It Me?

4. passing hash from a subroutine to other subroutine

5. Passing subroutine as an argument to another subroutine.

6. Q: passing array/hash from one subroutine to another subroutine

7. Passing one subroutine with parameters into another subroutine.

8. Perl5 passing subroutine refs to subroutines

9. Passing a subroutine as a parameter to another subroutine

10. Math::Matrix and matrix inversion

11. Fast file finder

12. Copying subroutines

 

 
Powered by phpBB® Forum Software