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

Dear monks,

Here is a code snippet that basically rollsup a line until the keyword end; is reached then it prints it out. I believe the approach i am taking is called a closure (please correct me if i am wrong).

#!/usr/bin/perl use strict; use warnings; my $dummy = ""; my $rollup = combine(""); my $oneline; while (<DATA>) { $rollup->($_); # once end is reached store it in a variable # reset variable-in-sub for next iteration if (/end;/) { # breaks if I remove $dummy and replace it with "" $oneline = $rollup->($dummy); $rollup = combine(""); print $oneline,$/; } } sub combine { my $concat = shift; return sub { chomp($_[0]); $concat .= $_[0]; return ($concat); } }
__DATA__ line1; line2; line3; end; line4; line5; end;
Expected Output:

line1;line2;line3;end; line4;line5;end;

The above code works just fine but when I use $oneline = $rollup->(""); instead of $oneline = $rollup->($dummy);

I get the following error -

Modification of a read-only value attempted at closure line 26, <DATA> + line 4.

Could you please explain to me what is the read-only value here?

I know i could do this whole step in a while loop and concatenate until end; is reached but wanted the flexibility in a sub and this also helps me learn more about closures :)

Thanks very much!

SK

Update: I have changed the title and took out the word closure as the problem is nothing to do with that.

Replies are listed 'Best First'.
Re: Modification of read-only value error when using closure
by Zaxo (Archbishop) on Aug 24, 2005 at 04:59 UTC

    The error is from attempting to modify $_[0] when the argument is a string literal, $rollup->(" ") rather than a variable $rollup->($dummy). The string literal is a constant, not an lvalue.

    After Compline,
    Zaxo

      Thanks Zaxo!!!

      I was under the impression that args are sent as values through @_ and thought that this problem was something to do with closures. I went back and tried a chomp on simple sub and the same happened. I checked perldoc perlsub and i got this info

      Any arguments passed in show up in the array @_. Therefore, if you ca +lled a function with two arguments, those would be stored in $_[0] an +d $_[1]. The array @_ is a local array, but its elements are aliases + for the actual scalar parameters. In particular, if an element $_[0 +] is updated, the corresponding argument is updated (or an error occu +rs if it is not updatable).

      Now it is clear to me!

      thanks again!

      cheers

      SK