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?