Grigor
Grigor

Reputation: 4059

Unable to understand reason for Tie::File failure

I have the following code

#!/usr/bin/perl
use Tie::File;

tie my @last_id, 'Tie::File', 'last_id.txt' or die "Unable to open this file !$i";
print @last_id[0];

exit;

and a file named last_id.txt with something like this in it

1
2
3
4
5
6

When I run the program nothing gets output. I tried $last_id[0] but still nothing. :/

I have latest ActivePerl installed.

EDIT:

Now I get the Unable to open this file message, but the file exists in the same directory as the program source file.

Upvotes: 2

Views: 1066

Answers (2)

Borodin
Borodin

Reputation: 126742

As you say, @last_id[0] is wrong and should be $last_id[0]. But this won't cause the problem you are seeing.

Note that the program won't look for last_id.txt in the same directory as the Perl source file unless it it also the current working directory.

You should first of all change the error variable used in the tie line to $! like this

tie my @last_id, 'Tie::File', 'last_id.txt'
    or die "Unable to open this file: $!";

as the variable $i contains nothing useful. This will tell you the reason for the failure of tie, which may be something other than no such file or directory.

You should also use strict and use warnings at the start of your program, as this will flag simple errors that are easy to overlook.

Finally, try fully-qualifying the filename by adding an absolute path to it. That will get around the problem of the program looking in the wrong directory by default.


Update

If the problem is that you have no write access to the file then you can fix it by opening it read-only.

You need the Fcntl module to define the O_RDONLY constant, so put this at the top of your program

use Fcntl 'O_RDONLY';

then the tie statement goes like this

tie my @last_id, 'Tie::File', 'last_id.txt', mode => O_RDONLY
    or die "Unable to open this file: $!";

Upvotes: 6

obmib
obmib

Reputation: 476

The problem should go away if you use absolute paths

BEGIN {
    use File::Spec;
    use File::Basename qw' dirname ';
    use vars qw' $thisfile $thisdir ';
    $thisfile = File::Spec->rel2abs(__FILE__);
    $thisdir  = dirname($thisfile);
}
...
tie ... "$thisdir/last_id.txt"

Upvotes: 1

Related Questions