Lobe
Lobe

Reputation: 538

Perl Modification of a read only variable

I am having a problem with a regex behaving in a manner that doesn't make sense to me. $line is a reference to a scalar (in this instance the string is 'print "hello world\n"') however the attempt to perform a regex match appears to succeed yet also change the value of $$line. In addition to this, I get an error when trying to modify $$line on line 65

Here is the code:

my $line = $_[0];
$$line =~ s/^(\s+\(?)//;
my @functions = ('print');
# Check if the expression is a function
for my $funcName (@functions) {
    print $$line . "\n";
    if ($$line =~ m/^($funcName\(?\s*)/) {
        print $$line . "\n";
        $$line =~ s/$1//; # THIS IS LINE 65
        my $args = [];
        while (scalar(@{$args}) == 0 || ${$line} =~ /\s*,/) {
            push (@{$args}, parseExpression($line))
        }
        my $function = {
            type => 'function',
            name => $funcName,
            args => $args
        };
        return $function;
    }
}

The output is as such:

print "hello world\n"
print 
Modification of a read-only value attempted at ./perl2python.pl line 65, <> line 3.

This code is an excerpt from a function, however it should be enough to illustrate what is going wrong.

The second line of the output should be the same as the first, but it appears $$line is being altered between the two print statements by the if clause.

Any advice??

Upvotes: 0

Views: 905

Answers (1)

DavidO
DavidO

Reputation: 13942

If you eliminate all the confusion belonging to code that is not part of the problem, eliminate the subroutine call, with its parameter passing, and so on, you could boil the problem down to code that looks something like this:

my $line = \"Hello world!\n"; # $line contains a reference to a string literal.
$$line =~ s/Hello/Goodbye/;

And when you run that, you will get the Modification of a read-only value attempted... message, because you cannot modify a string literal.

The fact that adding my somewhere fixed it may just mean that your new lexical $line masks some other scalar variable named $line, which was the one that held a reference to a string literal.

Upvotes: 5

Related Questions