in reply to Re^3: Strange modification of @_
in thread Strange modification of @_

I meant that both of the potential fixes for this feel unnatural:
  1. using s/(x)/fn "$1"/e (with quotes around $1), or
  2. using what you suggested: (my $new = $old)... or any other form of that.
Both fixes require an extraordinary amount of coupling between the caller and the function. Either:
  1. the caller needs to know that the argument to fn() will be used directly from @_ after a regexp, or
  2. the function needs to know that the argument is an alias of a global variable which will be modified by the regexp.
Only if they have this tight coupling does it make sense to use either of these two precautions to avoid the issue I ran into.

I think the takeaway for me is that when passing $1, etc into a function, that it should be quoted (to copy it), even though the general rule is when passing a variable $var into a function, (almost) never should it be quoted, as in fn("$var"). This feels exactly like the kind of kludgy rules you have to remember to use C++ "correctly".

Replies are listed 'Best First'.
Re^5: Strange modification of @_
by ikegami (Patriarch) on Apr 24, 2009 at 20:34 UTC
    1. the caller needs to know that the argument to fn() will be used directly from @_ after a regexp, or
    2. the function needs to know that the argument is an alias of a global variable which will be modified by the regexp.

    Not true. Just use the standard calling convention.

    sub f { my (...) = @_; ... }

    I think the takeaway for me is that when passing $1, etc into a function, that it should be quoted (to copy it)

    Maybe. I would have thought it was: There are risks in avoiding the standard calling convention.


    You're doing something unnatural then claim you have to take unnatural measures to avoid the resulting problems.

    You increase cohesion by using aliases then complain of the increased cohesion.

    What would like from us?

      Ikegami, I'm not sure what you're talking about. If you look at my original post, I did use my ($str) = @_;. I'm not avoiding the standard calling convention.

      What would like from us?

      Nothing. You answered my original question. (Thanks!) There doesn't seem to be any way around one of the two fixes I mentioned above and I don't like either of them (because they feel unnatural). I think the underlying problem is that $1 is a global and that interferes with the use of pass-by-reference.

        I'm not avoiding the standard calling convention.

        You may assign $_[0] to $str, but you also continue to use $_[0]. This continued use of @_ is the nonstandard element.