in reply to Read Only Error -- Sorting an Array

I've not been able to reproduce that error message. Generally that sort of message comes up when you do something like this:

for my $x ('x') { $x =~ s/x/X/ }

That is, when you have an alias to a literal, and you try to modify it. You can see a related error message like this:

'x' =~ s/x/X/;

Here are a few things wrong with your code...

Putting all this together, you get:

use strict; use Data::Dumper; my @data; while (<DATA>) { chomp; my @line = grep { defined $_ and length $_ } split /[()\t+\s+]/; push @data, \@line; } @data = sort { $a->[0] <=> $b->[0] } @data; print Dumper \@data; __DATA__ 00000(IDR) 86480 22 41.435 40.696 40.728167 0 FRM 3 00015( B ) 9312 24 45.460 43.808 42.001 409 208 FRM 0 00002( P ) 35248 24 38.568 39.327 40.641 253 53 FRM 2

I'd in fact go further and use Sort::Key to make that sort look a little nicer...

use strict; use Data::Dumper; use Sort::Key qw(nkeysort_inplace); my @data; while (<DATA>) { chomp; my @line = grep { defined $_ and length $_ } split /[()\t+\s+]/; push @data, \@line; } nkeysort_inplace { $_->[0] } @data; print Dumper \@data; __DATA__ 00000(IDR) 86480 22 41.435 40.696 40.728167 0 FRM 3 00015( B ) 9312 24 45.460 43.808 42.001 409 208 FRM 0 00002( P ) 35248 24 38.568 39.327 40.641 253 53 FRM 2
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^2: Read Only Error -- Sorting an Array
by perlstudent89 (Initiate) on Sep 18, 2012 at 02:50 UTC

    Your solution with grep is the one I eventually used. With the map implementation, I was throwing away the '0' numerals. Do you know why that is?

    I interpreted map {$_ ? $_ : ()} as saying, this such that this is whitespace. So then, why is it throwing away '0'? And length $_ solves this by keeping things that have a length? Since '0' has length of 1 but '' hasn't a length..?

      map { $_ ? $_ : () }

      means (if we pretend that there's a built-in function is_true()) the same as:

      map { if (is_true($_)) { $_; } else { (); } }

      In Perl, there are five things that are considered false: undef, the empty string, the number zero (including when written 0e0, 0.0, etc), the string "0" (but not strings like "0e0" or "0.0") and objects which overload conversion to boolean to return false.

      The zeros passing through your map are false, thus go down the "else" path.

      So we don't want to test is_true; we want to test whether each string has any characters... i.e. a non-zero length:

      map { length($_) ? $_ : () }

      Any any map which ends with ?$_:() should probably be a grep:

      grep { length($_) }
      perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
        Thanks for your thought out reply. Writing in Perl is becoming much easier thanks to you!