Modification of a read-only value attempted

The most common cause for this error is that perl attempted to write to a variable that is currently aliased to a constant.
The magic of $_ is often involved.

Possible causes:

Using magical $_ behaviour in non-trivial cases

The magical properties of $_ are great for saving a few keystrokes, but should be limited to use in small, strictly local blocks.

In this example the for loop is iterating over the literal values '1' and '2', aliasing $_ to them.

When the inner while loop reads a line from STDIN, it assigns the value to $_. This triggers the read-only error, because at this time $_ is the literal 1.

for (1,2) { while (<STDIN>) { } }
This error frequently occurs at a distance because a subroutine called within the loop modifies an unlocalized $_.

Treating a list as an array

The difference between a list and an array is often ignored, which can cause problems when modifying $_.

The intent in the following example is to iterate over two string literals, chomp the newline, and output the text:

for ("foo\n", "bar\n") { chomp; print; }
This causes the read-only error to occur, because within the context of that loop $_ is aliased to the string literal "foo\n".

Note that the problem is with the modification of the string literal. It is not directly related to $_. The error occurs with this as well:

for my $str ("foo\n", "bar\n") { chomp $str; print $str; }
map and grep are common sources for this problem as well.
@bad = map {$_++} (1,2); @bad = grep {$_++} (1,2);

Modifying @_ elements inside a subroutine

In this example the bad() subroutine attempts to modify the first parameter directly, using $_[0].
This causes problems if a literal value is passed.
sub bad { $_[0]++; } bad(1);

Modifying $a or $b inside sort

It is permissible (but ill-advised) to modify $a and $b within sort. (Tested for perl 5.6.2, 5.8.2, and 5.8.4)
my @good = (1,2); @good = sort {$a++ <=> $b} @good;
However, modifying a literal that is assigned to $a or $b is still an error.
@bad = sort {$a++ <=> $b} (1,2);

Dereferencing $a or $b inside a sort block without testing that they are references

Very closely related to the previous problem is the issue of dereferencing $a or $b when you do not know that they exist and are a reference. If $a is undefined and you attempt to use it as an array reference, perl will attempt to autovivify $a as an arrayref, which modifies the readonly value. Splode.
my @bad; $bad[0] = [1]; $bad[2] = [2]; @bad = sort {$a->[0] <=> $b->[0]} @bad;

Guidelines to avoid this error:

  1. Don't modify an unlocalized $_
  2. Don't modify $_ inside of map
  3. Don't modify $a or $b inside sort
  4. Don't dereference $a or $b inside sort without checking that they are references
  5. Don't use $_ for the loop variable unless it is a very trivial loop
  6. Don't modify elements of @_ directly

In reply to RFC - FAQ for Modification of a read-only value attempted by imp

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.