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

lets say i have a subroutine i want to pass a variable, and the sub should modify it, this would normally require passing a refreence:
#define the sub sub strip_space { # get our parameter my $val = $_[0]; # if not given a reference, return false return false if ref($val) ne "SCALAR"; # remove whitespace and retrn true on success $$val =~ s/\s+//g; return 1; } # and call said sub $test = "this will have no spaces!"; print $test if strip_space($test); print $test if strip_space(\$test);
the first print would never take place because a reference isnt passed to the sub, so it returns false, whereas the second print would work as expected. i remember to pass it a reference to a variable rather than just the variable itself.

but is there a way to not have to explicitly pass a reference to the sub? isnt there a way i can just use strip_space($test) every time and from within the sub grab a reference to $test?

Replies are listed 'Best First'.
Re: get a reference implicitly within a subroutine call?
by xdg (Monsignor) on Jun 23, 2006 at 15:16 UTC

    Just operate on $_[0] directly, as it aliases the parameter.

    #define the sub sub strip_space { # remove whitespace and retrn true on success $_[0] =~ s/\s+//g; return 1; }

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: get a reference implicitly within a subroutine call?
by shmem (Chancellor) on Jun 23, 2006 at 15:19 UTC
    You should re-read perlsub. There is stated:
    Because the assignment copies the values, this also has the eff +ect of turning call-by-reference into call-by-value. Otherwise a func +tion is free to do in-place modifications of @_ and change its caller's + values. upcase_in($v1, $v2); # this changes $v1 and $v2 sub upcase_in { for (@_) { tr/a-z/A-Z/ } }

    Of course you can take a reference to any value in @_ , but you were asking for modifying the caller's value, if I get it right.

    greets,
    --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}
Re: get a reference implicitly within a subroutine call?
by Zaxo (Archbishop) on Jun 23, 2006 at 15:20 UTC

    The elements of @_ are all aliases to the original arguments, so if they are lvalues they can be modified.

    sub strip_space { s/\s//g for @_; 1; } my $test = "this will have no spaces!"; strip_space($test); print $test,$/; __END__ thiswillhavenospaces!
    That will not work for constant arguments,
    # strip_space("this will have no spaces!"); # modification of constant error

    After Compline,
    Zaxo

Re: get a reference implicitly within a subroutine call?
by EvanK (Chaplain) on Jun 23, 2006 at 15:42 UTC
    As the posts above stated, @_ essentially contains references aliases to the original parameter values, so you'd just need to change $val = $_[0]; to $val = \$_[0];. and, of course, you could get rid of the ref() check :)

    EDIT: as L~R pointed out, i misspoke on the stricken-through part. the rest of the post is still correct though.

    __________
    Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.
    - Terry Pratchett

      EvanK,
      Where do any of the above posts state that @_ contains references? If it did contain references, then your code would be taking a reference to a reference. This may seem like I am being pedantic but there is a distinct difference between references and aliases and they can't be interchanged.

      Cheers - L~R