http://qs321.pair.com?node_id=261350

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

I wrote a module using cached hashes to access methods, as in the node A cacheing tied hash base class. The point is that you can access data using things like $object->{method}. After writing a moderately sided module around this, I've come across a strange bug. Depending on the way I call the method, sometimes I get a "Modification of a read-only value" error at the end of a file read.

Here's some code that reproduces the problem. Run it with the path to a file as an argument. The first way of calling the method will read and print out every line in the file, but the second way causes a fatal error, which occurs on the last line of the file (I think).

#!/bin/perl -w package My::Module; use vars qw(@ISA); use Carp; use Tie::Hash; @ISA = qw(Tie::StdHash); sub TIEHASH { my($class) = shift; my($self) = { }; bless $self, $class; } sub FETCH { my($self, $key) = @_; unless (exists $self->{$key}) { if (my $meth = $self->can($key)) { $self->{$key} = $meth->($self); } else { warn "No method for '$key'"; $self->{$key} = undef; } } return $self->{$key}; } sub new { my($class) = shift; my(%hash); tie %hash, $class; $hash{filename} = shift; return \%hash; } sub my_method { my $self = shift; open(IN, $self->{filename}) or croak "Couldn't open file $self->{f +ilename}: $!"; while (<IN>) { print; } close IN; } 1; package main; # THIS WORKS: my $obj1 = new My::Module($ARGV[0]); my $method = 'my_method'; print $obj1->{$method}; # THIS DOESNT WORK -- error message: # Modification of a read-only value attempted at /home/apirkle/perl/bu +g.pm line 41. my $obj2 = new My::Module($ARGV[0]); print $obj2->{$_} for (qw|my_method|); exit;
Any thoughts on why the second way of calling the method (in a for loop) doesn't work?