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

Dear Monks--

Once again I made a typo. Not sure whether it really matters--you may all have realized it, but please tell me.

In my earlier post ("sorting an array of arrays" ), I shifted midstream, first describing the name of the array I wanted to sort as
$courselist[$courseindex]
for the rest of the example I wrote
$courseindex[n]
All of the examples should have been
$courselist[0] = ["UM",......]

$courseindex was a simple indexing scalar.

However, I used the examples given to me and I'm getting the error message I referenced in that first post, to wit:
"Modification of a read-only value attempted"

And I'm thoroughly puzzled. I apologize for my bad proof-reading skills. Please help!

2006-08-14 Retitled by GrandFather, as per Monastery guidelines
Original title: 'sorting an array of arrays Pt 2'

Replies are listed 'Best First'.
Re: How to fix error: Modification of a read-only value
by Corion (Patriarch) on Aug 13, 2006 at 14:38 UTC

    Then and now, you haven't shown us the (reduced) code and the (relevant) data that reproduce the error you're getting. Please reduce your code to a self contained (say, 20 line) script, and supply sample data (say, 5 items), so we can look at it all.

    From the error message, my guess is that somewhere in your code (Perl tells you the line number, but you keep it from us as if it's some secret), you're modifying a read-only value. Normally, Perl catches such attempts right away:

    perl -e "print 1++" Can't modify constant item in postincrement (++) at -e line 1, near "1 +++" Execution of -e aborted due to compilation errors.

    ... but you can be more tricky and then Perl can't detect such errors until you execute the code:

    sub incr { $_[0]++ }; incr($foo); incr(1);

    Maybe you are trying to assign to other read-only values, like $1 or something. We don't know, and it's quite hard to guess without seeing the code.

Re: How to fix error: Modification of a read-only value
by graff (Chancellor) on Aug 13, 2006 at 14:52 UTC
    However, I used the examples given to me and I'm getting the error message I referenced in that first post, to wit: "Modification of a read-only value attempted"

    I doubt that anyone here can answer this question (or this part of the earlier post) based on the information you have given in both posts combined.

    Error messages like this tell you which line number in your script has caused the error. You have to show us at least that line of code, along with any other lines of code that are relevant -- that is: for whatever variables are present in the line that causes the error, show us at least the lines where those variables are declared and where values are assigned to them prior to the line that causes the error.

    Nothing in the examples given to you in the previous thread would generate this error. None of the code you've posted so far would generate this error. (You haven't posted enough code to show whether it would generate this error.) So you need to show more of your code.

    If the code is not ridiculously long, post the whole script. (Do it as an update or reply to this thread, please. Two places for discussing the same problem are more than enough.)

Re: How to fix error: Modification of a read-only value
by GrandFather (Saint) on Aug 13, 2006 at 20:56 UTC

    Note too that this would have been better as an update to your original question to keep the question and answers cohesive. Are you going to post the code you have been asked for here, or in the original thread?

    If someone else with the same problem happens on your thread, but can't find the answer because the answer is in the other thread how does that help you return the consideration others have shown in answering you. In fact splitting your question in this fashion may make it less likely that you will get an answer - savy monks will notice the effect of diluting their effort and will turn their attentions to more worthy seekers.

    Ah rats, strike that. I re-read your original node after coffee, and this node has nothing whatsoever to do with the array sorting question. In fact a different name would help a great deal - you may find it spontaniously changes in the next few hours even.

    As others have suggested, you really need to post the lines of code exhibiting the error. A very good thing to do is reduce the code to a small number of lines showing the issue and post that. See I know what I mean. Why don't you? for some ideas on how to do that.

    Although actually we have a pretty good track record at reading minds, sometimes we simply fail and have to be helped out with some actual information. This seems to be one of those times.


    DWIM is Perl's answer to Gödel
Re: How to fix error: Modification of a read-only value
by Gnat53 (Novice) on Aug 13, 2006 at 21:27 UTC
    Dear Monks--
    Sorry if I haven't provided enough information

    O.K. Here is all the code I can think is relevant. You wanted to know what line was generating the error ("Modification of a read-only value attempted"). It was the last line I'm giving here; i.e. the sort line. Is it worth noting that elsewhere in the program I am able to access any element of the @courselist array without problem?
    foreach $try (@text){ $try =~/^(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?)\|(.*?) +\|(.*?)\|(.*?)$/gs or die "<br />problem with $try<br />"; my $Institution = $1; my $CourseNumber = $2; my $Professor = $3; my $Enrollment = $4; ........ if (!$CourseNumber && !$Institution){last;}; if ($CourseNumber ne $LastCourseNumber){ $courseindex = $courseindex + 1; $courselist[$courseindex] = [$Institution, $CourseNumber, $Professor, +$CourseTitle, $Enrollment]; }; $LastCourseNumber = $CourseNumber; }; @courselist = sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @co +urselist;
    To reiterate, what I'd like to do is to sort @courselist by $courselist[n][0] (i.e. $Institution, and within that sort, by $courselist[n][1], i.e. $CourseNumber.

    This is an example of what I have in @courselist:
    $courselist[0] = ["UM", "CS 34", "Smith", "34"] $courselist[1] = ["AC", "PHIL 13", "Barry", "45"] $courselist[2] = ["UM", "BIO 567", "Houlihan", "12"]
    and I want it to end looking like this:
    $courselist[0] = ["AC", "PHIL 13", "Barry", "45"] $courselist[1] = ["UM", "BIO 567", "Houlihan", "12"] $courselist[2] = ["UM", "CS 34", "Smith", "34"]

    I don't understand why I'm getting the error message, and I'm still not sure about the sort...

    Thanks for your continuing efforts!

      This is still not a piece of code that I can run on my machine and see your problem. Distil your code down to a stand alone sample that exhibits the problem. There are too many unknowns in the code you have provided. I say again, read I know what I mean. Why don't you?.

      Note that your regex is probably much better done as a split:

      my ($Institution, $CourseNumber, $Professor, $Enrollment) = split '|', + $try;

      Oh, hold on a moment, my esp cells are kicking in. Here is the sample you should have posted:

      use warnings; use strict; my @courselist; my @text = 'UM|CS 34|Smith|34'; my $courseindex = 0; foreach my $try (@text){ my ($Institution, $CourseNumber, $Professor, $Enrollment) = split +'|', $try; $courseindex = $courseindex + 1; $courselist[$courseindex] = [$Institution, $CourseNumber, $Professor, $Enrollment]; }; @courselist = sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1]} @cou +rselist;

      And the answer is that you preincrement $courseindex so the first element is placed at index 1, but Perl generally starts arrays at 0 and trying to dereference aan undefined value in the sort (element 0) is generating your error.

      Your code would be better written as:

      use warnings; use strict; my @courselist; my @text = 'UM|CS 34|Smith|34'; foreach my $try (@text){ my ($Institution, $CourseNumber, $Professor, $Enrollment) = split +'|', $try; push @courselist, [$Institution, $CourseNumber, $Professor, $Enrol +lment]; }; @courselist = sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1]} @cou +rselist;

      DWIM is Perl's answer to Gödel
      Here is all the code I can think is relevant.

      Well, you might need to think a little harder -- or read our replies more carefully... But, okay, here is a working script based on what you've posted, putting together some sample data from your earlier post, and adding some other things that you haven't included yet, like assigning data to @text. (I removed "$CourseTitle", but if you really need it, I hope you can figure out how to fit it in with this approach.) Essentially, I'm providing the thing that GrandFather asked for (except that this version does not get the run-time error that you get, so it doesn't "demonstrate the problem"):

      use strict; use Data::Dumper; my @text = <DATA>; my @courselist; my $LastCourseNumber; for (@text) { my ( $Institution, $CourseNumber, $Professor, $Enrollment ) = spli +t /\|/; last unless ( $CourseNumber && $Institution); if ($CourseNumber ne $LastCourseNumber) { push @courselist, [ $Institution, $CourseNumber, $Professor, $Enrollment]; $LastCourseNumber = $CourseNumber; } } print Dumper( \@courselist ); @courselist = sort { $a->[0] cmp $b->[0] || $a->[1] cmp $b->[1] } @co +urselist; print Dumper( \@courselist ); __DATA__ UM|CS 34|Somebody|3 AC|PHIL 13|Another Person|8 UM|BIO 567|Someone Else|20
      (update: the "last" condition in loop had been like the OP code ("if..."), but I think using "unless" makes more sense here -- this way, either variable being empty will exit the loop.)

      This does what you want to do (sort the array). I expect there's still more stuff in your own script that you need to fold in, and maybe when that other stuff is included, you'll still get an error. If so, that means the problem is still somewhere in the code that you have not shown us.

      Don't say
      $courseindex = $courseindex + 1;

      say rather

      $courseindex++;
      if you need $courseindex for anything other than storing the array references in the right slot of @courselist.

      You should then set $courseindex initially to 0 and increment it at the proper place, i.e. after having filled an array slot.

      If you don't need to keep track of the index and just want to push a value (anonymous array) onto @courselist, do so:

      push @courselist, [$Institution, $CourseNumber, $Professor, $CourseTit +le, $Enrollment];

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: sorting an array of arrays Pt 2
by Gnat53 (Novice) on Aug 20, 2006 at 15:47 UTC
    Dear Monks--
    Sorry if I haven't provided enough information

    O.K. Here is all the code I can think is relevant. You wanted to know what line was generating the error ("Modification of a read-only value attempted"). It was the last line I'm giving here