To avoid changing the originals, you can write
sub mySubst { map { (my $s=$_) =~ s|abc|xyz|ig; $s } @_ }
or
sub mySubst { my @a = @_; map { s|abc|xyz|ig; $_ } @a }
or borrow an answer from Sinan, except that it explicitly discards the temporary array:
sub mySubst { map { s|abc|xyz|ig; $_ } my(undef) = @_ }
but the syntax is still a bit noisy. Since it uses map , be sure to call it in the context of the list:
my($result) = mySubst $str;
If you usually call mySubst with a single argument, but want to handle cases of one or more arguments, you can write
sub mySubst { s|abc|xyz|ig for my @a = @_; wantarray ? @a : $a[0]; }
but it will start stuttering again.
If you want to update the parameter itself, use the semantics of Perl subset aliases, as described in perlsub :
The @_ array is a local array, but its elements are aliases for real scalar parameters. In particular, if the element $_[0] updated, the corresponding argument is updated (or an error occurs if it is not updated).
So you can write
sub mySubst { $_[0] =~ s|abc|xyz|ig }
or even
sub mySubst { map { s|abc|xyz|ig; $_ } @_ }
Usage example:
$str = "fooabcbar"; mySubst $str; print $str, "\n";
Conclusion:
fooxyzbar