in reply to Closure producing 'Modification of read-only value' error

The $_ of your for loop is aliased to the read-only strings qw(one two three). The while loop inside the sub overwrites $_, hence the "Modification of a read-only value attempted" error. If you add the line:

local $_;
inside your sub get_number it works. Generally, mangling $_ inside a subroutine is poor form.

Update: a cleaner way to ensure the sub plays well with others is to simply change the while loop to use a lexical rather than the implicit $_:

while (defined(my $d = <DATA>)){ chomp $d; my ($str, $num) = split /\|/, $d; $hash_ref->{$str} = $num; }

Replies are listed 'Best First'.
Re^2: Closure producing 'Modification of read-only value' error
by nobull (Friar) on Jun 11, 2005 at 11:04 UTC
    No, don't do that.

    Never local $_ in a subroutine. If you want to use the magic assignment you should do local *_. Of course you have to unpack anything you want from @_ first.

    If you get into the habit of doing local $_ inside you subroutines it will seem to work fine - maybe for years. Then one day someone will call one of your subroutines inside a for() loop that is iterating over the values of a tied array or hash. Very odd things will start happening in their program.

      What about the implicit localizations of $_ done by map, grep, for, etc.? Do they do The Right Thing®?

      I think it is surprising (hence bad) that the while ( <FH> ) idiom doesn't do an implicit localization of $_ like the looping constructs listed above. Is there a fundamental reason for this, or is it due to a severe tuit shortage?

      the lowliest monk

        map, grep, for etc do the right thing.

        The magic while construct does not make $_ and alias - it assigns to it. This is fundamentally different. That said, it bugs me that it doesn't do implicit localization.

      I'm sorry, maybe I'm dense, but what exactly is different when you iterate over a tied array or hash. What are these "very odd things" and why won't a simple local $_ do? This is very interesting to me.