Subhayan Bhattacharya Subhayan Bhattacharya - 10 months ago 38
Perl Question

Tiescalar in Perl

I have written the below module as the module to tie my scalar to a particular file contents :

package Scalar;
use strict;
my $count = 0;
use Carp;

print "Inside TIESCALAR function \n";
my $class = shift;
my $filename = shift;
if ( ! -e $filename )
croak "Filename : $filename does not exist !";
if ( ! -r $filename || ! -w $filename )
croak "Filename : $filename is not readable or writable !";
return \$filename , $class;

sub FETCH {
print "Inside FETCH function \n";
my $self = shift;
croak "I am not a class method" unless ref $self;
my $myfile = $$self;
open (FILE , "<$myfile") || die "Can't open the file for read operation $! \n";
flock(FILE,1) || die "Could not apply a shared lock $!";
my @contents = <FILE>;
close FILE;

sub STORE {
print "Inside STORE function \n";
my $self = shift;
my $value = shift;
croak "I am not a class method" unless ref $self;
my $myfile = $$self;
open (FILE , ">>$myfile") or die "Can't open the file for write operation $! \n";
print FILE $value;
close FILE;



The code through which i call this module is as follows :

use strict;
use Scalar;

my $file = "test.dat";

my $filevar = undef;
tie ($filevar, "Scalar", $file) or die "Can't tie $!";

print "Trying to retrieve file contents \n";
my $contents = $filevar;
foreach (@{$contents})
print "$_";

print "Trying to add a line to file \n";
$filevar = "This is a test line added";

print "Reading contents again \n";
$contents = $filevar;
foreach (@$contents)
print "$_";

When i try to run this code , the below message comes up :

Inside TIESCALAR function
Trying to retrieve file contents
Trying to add a line to file
Reading contents again
Can't use string ("This is a test line added") as an ARRAY ref while "strict refs" in use at line 21.

I don't think the code is going into the FETCH and STORE functions of the module . Can someone please point out what the issue here is ?


I think the root of your problem will be that you don't actually bless your value.

With reference to an example: Automatically call hash values that are subroutine references

I think you need to change the last line of TIESCALAR to:

return bless \$filename, $class;

Otherwise all it's doing is 'returning' the filename and not tying it.

I can't entirely reproduce your problem - but I think you will also have problems with the implicit return of your FETCH which doesn't actually return the @contents but rather the return code of close.

I would also suggest - 3 argument open is good, especially when you're doing something like this, because otherwise FILE is a global, and can be clobbered.