How to pass 2D array to sub function and return 2D array?

Discussion in 'Perl Misc' started by Davy, Aug 3, 2006.

  1. Davy

    Davy Guest

    Hi all,

    I want to pass 2D array to sub function and return 2D array.

    //--------------------------
    For example,
    use strict;
    use warnings;
    my @array=([1,2,3],[4,5,6],[7,8,9]);
    my $array_ref = \@array;

    $array_r = increase_array_element($array_ref);

    sub increase_array_element {
    //recover the 2D array
    my @array_tmp = @{$array_ref};
    print $array_tmp[2][2];
    return \@array_tmp;
    }
    //-------------------------

    But it seems the compile did not think @array_tmp is a 2D array?

    Thanks!
    Davy
     
    Davy, Aug 3, 2006
    #1
    1. Advertisements

  2. Davy

    Sisyphus Guest

    Best to copy'n'paste code. The code you have posted won't compile.

    Just as inside the subroutine where you dereferenced the array reference
    ($array_ref) to an array (@array_temp), you could do the same with $array_r
    (which is also an array reference - since that is what the subroutine
    returns).

    Something like:

    use strict;
    use warnings;
    my @array=([1,2,3],[4,5,6],[7,8,9]);
    my $array_ref = \@array;

    my $array_r = increase_array_element($array_ref);
    my @array_r_r = @{$array_r};
    print $array_r_r[1][1], "\n";

    sub increase_array_element {
    my @array_tmp = @{$array_ref};
    print $array_tmp[2][2], "\n";
    return \@array_tmp;
    }

    Cheers,
    Rob
     
    Sisyphus, Aug 3, 2006
    #2
    1. Advertisements

  3. Davy

    anno4000 Guest

    That's not a valid Perl comment. It's a fatal error.
    $array_r is undeclared. That's a fatal error under "strict".

    Calling "increase_array_ref" with an argument is useless because
    the sub doesn't look at its arguments.
    See above.
    How do you know that?

    Your code doesn't compile at all, you didn't even bother to run it
    before posting.

    Make your program runnable. If it still doesn't do what you expect,
    post again, explaining what you expected and what happens instead.

    Anno
     
    anno4000, Aug 3, 2006
    #3
  4. Davy

    Paul Lalli Guest


    This code contains the same error as the OP's. You are passing this
    subroutine an argument, but never obtaining that argument from within
    the subroutine. It will "work" simply because the argument you passed
    was declared within the scope of both the function definition and the
    function call, but that's not what you want to do.

    sub increase_array_element {
    my @array_temp = @{$_[0]};
    $array_tmp[2][2]++;
    print $array_tmp[2][2], "\n";
    return \@array_tmp;
    }

    Please note that because of the way multi-dimensional structures work
    in Perl, both the original and modified arrays contain references to
    the *same* arrays, and so you have actually modified both $array_r and
    $array_ref. . .

    Paul Lalli
     
    Paul Lalli, Aug 3, 2006
    #4
  5. Davy

    Sisyphus Guest

    ..
    ..
    The code I posted does not contain any errors.

    I was aware that the OP's subroutine took no arguments. If I had also
    noticed that the OP was calling the subroutine *with* an argument then I
    would have amended that when I did the copy'n'paste of his code. I did not
    notice the OP had done this until Anno pointed it out.

    It's good that you took the time to explain how to pass the argument to the
    subroutine. I ignored that aspect because (I thought) the question asked was
    concerned with the sub's *return* value - but given the subject line, your
    explanation is certainly warranted.

    Cheers,
    Rob
     
    Sisyphus, Aug 3, 2006
    #5
  6. Davy

    Paul Lalli Guest

    It does not contain any errors in that it will, indeed, work exactly as
    posted. However, the general methodology given by your example will
    not. Passing an argument into a subroutine and later referring to that
    argument in the subroutine by the name it had as an argument to the
    function call is an error. Because it "works" under a specific
    circumstance (the call and the definition being in the same scope) does
    not make it not an error.

    Paul Lalli
     
    Paul Lalli, Aug 3, 2006
    #6
  7. Davy

    Davy Guest

    Hi Lalli,

    I have used your code and passed, thanks!

    Davy

     
    Davy, Aug 4, 2006
    #7
  8. Davy

    Davy Guest

    No, I use Perl in my work. And I found reference in Perl is not so
    clear as in C.

    Anyhow, thanks.
    Davy
     
    Davy, Aug 4, 2006
    #8
  9. Davy

    Uri Guttman Guest

    D> No, I use Perl in my work. And I found reference in Perl is not so
    D> clear as in C.

    well, considering they are dramatically different, why should they be as
    clear? c uses raw address pointers which can be manipulated, cast and
    broken in too many ways to count. perl uses intelligent references which
    can only be created by perl, can't be directly manipulated by user code
    (no segfaults from perl refs) and can only be dereferenced to the
    original thing that was referenced. does that sound like they are so
    similar that knowing c pointers would make it clear how perl's refs
    work? they have almost nothing in common.

    and if you think c's pointers are clear and perl's refs are not, you
    haven't done much deep data work and coding in either lang. i have done
    plenty in both and i much prefer perl's refs. tracking segfaults is not
    how i want to spend the rest of my life.

    uri
     
    Uri Guttman, Aug 4, 2006
    #9
  10. Davy

    Davy Guest

    Hi,

    I understand. c's pointers are too flexible to generate bugs and Perl's
    reference is more strict. Thanks!

    Davy
     
    Davy, Aug 4, 2006
    #10
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.