Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

passing reference to subroutine

by asthaonard (Acolyte)
on Oct 28, 2011 at 07:58 UTC ( [id://934329]=perlquestion: print w/replies, xml ) Need Help??

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

Hello

I need some advise in, i think, very trivial situation. I want to undef an array in a sub, but somehow it still exists outside that sub.

My code follows

use strict; use warnings; use Data::Dumper; sub undef_ref { my $ref = shift; my @struct = @$ref; undef @struct; print '='x20; print"\n"; print Dumper(@struct); } my @struct = ('a','b','c','d','e'); undef_ref(\@struct); print '='x20; print"\n"; print Dumper(@struct);

What am I missing?

Replies are listed 'Best First'.
Re: passing reference to subroutine
by chromatic (Archbishop) on Oct 28, 2011 at 08:09 UTC

    Two things. First, I think you want to empty an array. Do that by assigning it an empty list.

    Second, your copy the values out of the reference into a new array and modifies the copy, not the original.


    Improve your skills with Modern Perl: the free book.

Re: passing reference to subroutine
by GrandFather (Saint) on Oct 28, 2011 at 08:12 UTC

    I think you've removed too much context for any answer to actually solve the problem you haven't described. However I'll address the question as posed just in case it does have some bearing on your actual problem.

    The sub call passes a reference to an array into the sub - so far so good. Note though that @struct outside the sub has nothing to do with @struct inside the sub: It would be clearer to choose a different name for one of the arrays.

    In the sub $ref gets a copy of the passed in array reference. A copy of the elements in the referenced array is then made and placed into the sub's @struct - a copy note!

    undef @struct; (better written as @struct = (); btw) clears out the array containing a copy of the original array.

    The important thing to realise here is that nothing done in the sub affects the original array because all the work is done on a copy of the contents of the original array.

    True laziness is hard work
      undef @struct; (better written as @struct = (); btw)

      Not if the goal is to free up space rather than just empty it for reuse:

      @a = 1..1e6;; print total_size \@a;; 32000176 @a = ();; print total_size \@a;; 8000176 undef @a;; print total_size \@a;; 176

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      i see... but how would i avoid that copying? How should i dereference my variable correctly?

        What do you really want to do? The dereference is as simple as undef @$ref; (see below for the entire updated sub), but I have the strong feeling that you are asking the wrong question and providing the wrong sample code. It seems extraordinary that you would call a sub just to clear an array!

        sub undef_ref { my $ref = shift; undef @$ref; print '=' x 20; print "\n"; print Dumper (@$ref); }
        True laziness is hard work

        It's worth the time to have a look at perlreftut -- the simple reference tutorial :)

Re: passing reference to subroutine
by BrowserUk (Patriarch) on Oct 28, 2011 at 08:42 UTC

    You can achieve your goal thus:

    sub undefRef{ my $ref = shift; undef @{ $ref }; }

    But why you would do undefRef( \@a ); rather than undef @a; I cannot see.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      it was just an example :) what I'm trying to do is modification of passed in array

      thanks for help

        modification of passed in array
        You may have good reasons to do that but when I'm faced with similar situations I wonder if returning a new version of the array might be better/safer.
        #! /usr/perl/bin use warnings; use strict; use Data::Dumper; sub process_array_ref { my $initial_array_ref = shift; my @processed_array; for my $element (@{$initial_array_ref}){ # do something with element # validate, normalise, error checking, # convert to metric, skip, whatever push @processed_array, sprintf(qq{processed: %s}, $element); } return \@processed_array; } my $initial_array_ref = ['a','b','c','d','e']; my $processed_array_ref = process_array_ref($initial_array_ref); print Dumper($processed_array_ref);
        I often find that debugging/maintainance is easier with this approach. YMMV.
Re: passing reference to subroutine
by mrstlee (Beadle) on Oct 28, 2011 at 11:56 UTC
    undef will work just fine on the de-refd ref passed to the sub-routine:
    use strict; use warnings; use Data::Dumper; sub undef_ref { my $ref = shift; my @struct = @$ref; undef @$ref; ## Blow away original print '='x20; print"\nStruct is\n"; print Dumper(@struct),"\nIn undef_ref\n"; } my @struct = ('a','b','c','d','e'); undef_ref(\@struct); print '='x20; print"\n"; print "Struct is\n",Dumper(@struct),"\nOutside undef_ref\n";
    The perlreftut & perlref pages in the core documentation is a great place to start.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://934329]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (7)
As of 2024-04-24 11:40 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found