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

Supposing you have
my $ref = \"stuff";
then I know this is a reference to a literal string, and I would be a bit silly to try
$$ref =~ s/u/i/; ## or even $$ref .= " and more stuff";
But, I have this function that modifies a string, and is designed to modify the actual value:
sub modify_string{ my $arg = \shift; ## $$arg is modified, no need for the details, eg $$arg =~ s/u/i/; return $$arg; }
so now I can say
my $string = "stuff"; modify_string( $string ); ## or even my $copy = modify_string( $string );
Now, some time later I wrote:
my $new_string = modify_string ( "literal stuff" );
And to my surprise this works fine! I tested my new code on my ActivePerl 5.6.0 and everything was cool and dandy, so I think, just another of the Perl magic DWIMs.

Then I moved the code to the unix server, also running 5.6.0, it all fell over in a heap. Or I should say, gave the error I expected in the first place: Attempt to modify constant value.

So does anyone (a) know why there is the difference (b) which one is correct and (c) do I need a slapping for writing $arg = \shift; in the first place??

iakobski

Replies are listed 'Best First'.
Re: Modifying a reference to a literal string
by hdp (Beadle) on May 02, 2001 at 19:53 UTC
    I'm not sure why there's a difference -- I don't have a windows machine to test it on, but I would have expected the "attempt to modify readonly value" error everywhere.

    Keep in mind that you can directly modify the parameters passed to a function by messing with @_. You don't need to use \shift; I suggest rewriting modify_string as:

    sub modify_string { $_[0] =~ s/u/i/; return $_[0]; }
    Your way isn't "wrong", but (relatively) it does a lot of extra work.

    hdp.