Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

How to pass by reference

by tanyeun (Sexton)
on Jul 31, 2006 at 07:07 UTC ( #564694=perlquestion: print w/ replies, xml ) Need Help??
tanyeun has asked for the wisdom of the Perl Monks concerning the following question:

Hi, monks,
$x = 10; &function($x); # if I change $x = 5 print $x; # $x = 10
How should I do to pass by reference
if I want $x to be 5
Presently, I let $x to be global variable
and use &function() to change the variable value
but I know it's not a good idea in big projects

Comment on How to pass by reference
Download Code
Re: How to pass by reference
by bbfu (Curate) on Jul 31, 2006 at 07:15 UTC

    There's a couple of options. You can use the aliasing behavior of @_, or you can pass an actual reference.

    sub func_alias { $_[0] = 5; } sub func_ref { my $ref = shift; $$ref = 5; } my $x; func_alias($x); print "x = $x\n"; my $y; func_ref(\$y); print "y = $y\n";

    The latter is probably better, as it is less likely to cause surprise the caller (ie, it's more explicit that you're potentially modifying the function parameter).

    bbfu
    Black flowers blossom
    Fearless on my breath

Re: How to pass by reference
by GhodMode (Pilgrim) on Jul 31, 2006 at 07:20 UTC

    Just put a backslash in front of the dollar-sign when you pass the variable to the function.

    Don't forget to de-reference the variable inside the function ...

    use strict; use warnings; my $x = 10; &function( \$x ); # if I change $x = 5 print $x; # $x = 10 sub function { my $x = $_[0]; $$x = 5; } # End function subroutine

    --
    -- Ghodmode
    
    Blessed is he who has found his work; let him ask no other blessedness.
    -- Thomas Carlyle
Re: How to pass by reference
by davorg (Chancellor) on Jul 31, 2006 at 07:52 UTC

    You've already got a good answer explaining what you need to know.

    I just wanted to add that for about the last ten years there have been very few occasions when you need to put the '&' on the front of a function call. Unless you know that you need it (and in 99% of cases - including this one - you don't) then you should leave it off.

    And if you got that bad habit from a book or an online tutorial then you should view any other information that you got from the same place with deep suspicion.

    --
    <http://dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      I learned that from Randal's Learning Perl
      it tells that '&' can be omit if
      there's no built-in function that
      has the same name of yours
      because I wasn't sure which subroutine name
      I use will clash that of the built-in function
      so I always add '&' in the front
      I don't know it is a bad habit.
      so why it is a bad habit anyway?
        From perlsub:
        &NAME; # Makes current @_ visible to called subroutine.
        and
        A subroutine may be called using an explicit "&" prefix. The "&" is optional in modern Perl, as are parentheses if the subroutine has been predeclared. The "&" is not optional when just naming the subroutine, such as when it's used as an argument to defined() or undef(). Nor is it optional when you want to do an indirect subroutine call with a subroutine name or reference using the "&$subref()" or "&{$subref}()" constructs, although the "$subref->()" notation solves that problem. See perlref for more about all that.

        Subroutines may be called recursively. If a subroutine is called using the "&" form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

        &foo(1,2,3); # pass three arguments foo(1,2,3); # the same foo(); # pass a null list &foo(); # the same &foo; # foo() get current args, like foo(@_) !! foo; # like foo() IFF sub foo predeclared, else " foo"
        Not only does the "&" form make the argument list optional, it also disables any prototype checking on arguments you do provide. This is partly for historical reasons, and partly for having a convenient way to cheat if you know what you're doing. See Prototypes below.

        So, two points with '&' here: 1) propagates @_ implicitly, 2) bypasses prototype checking. If any of them is what you want, using '&' is fine; else not.

        --shmem

        _($_=" "x(1<<5)."?\n".q/)Oo.  G\        /
                                      /\_/(q    /
        ----------------------------  \__(m.====.(_("always off the crowd"))."
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

        Well, the (admittedly small) danger is that a call like &bar will pass on the current value of @_ to bar. That's almost never what you want. And even if it _is_ what you want, you'll confuse a maintenance programmer unless you write it as &bar(@_) (or bar(@_)).

        #!/usr/bin/perl sub foo { &bar(1, 2, 3); &bar; # silently passes on @_ } sub bar { print "@_\n"; } &foo('a', 'b', 'c');

        Also, in general, less punctuation is good - as the less there is to type, the less there is to get wrong :-)

        --
        <http://dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2014-07-26 05:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (175 votes), past polls