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

I've finally figured out that the automatic testing for CPAN is a little less flawed than I thought. Lately I have run into email that I had taken to mean that the necessary module was not installed and dismissed the error reports as nonsense. Only to find out today that I get the same error. After bashing my head for too long, I've reduced it to a small test.

Given:
#!/usr/bin/perl # test.pl -- use strict; use warnings; use diagnostics; use DB_File; my %hash; my $db_path = './db/'; for (@INC) { if (-d "$_/Chess/PGN/db") { $db_path = "$_/Chess/PGN/db/"; last; } } my $filename = "${db_path}ECO"; open TEST, "<$filename" or die "Couldn't open $filename:$!"; close TEST; #-----line 19 follows----- tie (%hash, "DB_File", $filename) or die "Couldn't tie $filename: $!\n";
I get:
C:>test Uncaught exception from user code: Couldn't open C:/Perl/site/lib/Chess/PGN/db/ECO: No such file +or directory at C:\Perl_Dev\Openings for Russ\test.pl line 19
The file does exist on my box and for that matter if you set $file to 'test.pl', you still get the same failure. This suggests that I'm not using 'tie' correctly---which I'm perfectly willing to believe even though this example code came from the 3rd edition camel and matches code in 21 previously working distributions<sigh!>

So fellow monks, any clues for the clueless?

Update: Added marker for line 19 and changed the die statement for the tie attempt.

--hsm

"Never try to teach a pig to sing...it wastes your time and it annoys the pig."

Replies are listed 'Best First'.
Re: A problem with tie
by merlyn (Sage) on Mar 04, 2005 at 22:18 UTC
      Wish it was but if you add some sort of flag to the die statements you still crash on the 'tie':
      C:>test Uncaught exception from user code: [tie]Couldn't open C:/Perl/site/lib/Chess/PGN/db/ECO: No such +file or directory at C:\Perl_Dev\Openings for Russ\test.pl line 19

      --hsm

      "Never try to teach a pig to sing...it wastes your time and it annoys the pig."
        I suggest that you update the top node to use different messages for the "open" die and the "tie" die. Something as simple as changing "Couldn't open" to "Couldn't tie". Also, you might want to add a message after the close statement to show explicitly that you're getting past that stage.

        Some people may go through your code to find which die is at line 19, but clearly the first few posters here didn't. It's all about helping people highlight what's going wrong. (Though I think that my reply elsewhere answers what's going wrong)

        -- @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
Re: A problem with tie
by cowboy (Friar) on Mar 04, 2005 at 22:37 UTC
    You are trying to open a non-existant file for reading.
    tie will happily create the file for you, but you die before that.
    Remove the (seemingly) useless open call, and it should work fine.
Re: A problem with tie
by fizbin (Chaplain) on Mar 05, 2005 at 04:57 UTC
    The file db/ECO may exist, but it is corrupt. I get this error on windows if I first create a file called db/ECO. On Linux, I get a different message:
    Uncaught exception from user code: tie said Couldn't open ./db/ECO: Inappropriate ioctl for devic +e
    Also, on Linux I can create the file with touch to create an empty file, and that solves the problem. However, on Windows, an empty file isn't good enough - empty files still throw back the same error.

    But the error goes away if I properly create the file as a correct DB_File:

    C:\temp\t>del db\ECO
    
    C:\temp\t>perl -MDB_File -e "tie(%E,q(DB_File),q(db/ECO))"
    
    C:\temp\t>perl test.pl
    no output

    So I think that's your problem - this ECO file isn't a valid DB file, and there's something a slight bit off about the way that DB_File sets $! on Windows, such that it gives the wrong error message. (Probably all that confusion about errno vs. bsderrno that goes on with dbm stuff)

    -- @/=map{[/./g]}qw/.h_nJ Xapou cets krht ele_ r_ra/; map{y/X_/\n /;print}map{pop@$_}@/for@/
      I willl certainly check on this although I would make a few observations, this is revision 22 in a series for this particular CPAN module. It works fine under 5.6. Do you suppose that some newness in DB_File might be the problem, for instance I can tell you that the files in question were generated by an older version, possibly a much older version. I think having just said that I will revisit the process where by I built the files in the first place, delete and rebuild and then retest---this feels like a likely thing to do just to be safe anyway. Thanks!!

      Update: The problem was in fact a version problem. DB_File of course changes over time as do most things perl. And not to surprisingly it wasn't backwards compatible (typically a race that can't be won anyway) and I was partially stung by that and by how I build new releases. Since changes involve iterative testing I don't bother to re-create the db files after the new versions for the release are created. Silly me! In this case that meant the versions in my dev directory were out of synch with what I actually wanted. Note to self---revise test/build procedures to eliminate dangerous assumptions (redundant for emphasis). Thanks to all!!

      --hsm

      "Never try to teach a pig to sing...it wastes your time and it annoys the pig."
Re: A problem with tie
by jdalbec (Deacon) on Mar 05, 2005 at 02:33 UTC
    What happens if you add $filename=~s./.\\.g; before the tie?
      I've tried both style slashes with no effect. Also as I mentioned this fails even if you try and open the script itself with no slashes.

      --hsm

      "Never try to teach a pig to sing...it wastes your time and it annoys the pig."
Re: A problem with tie
by nobull (Friar) on Mar 05, 2005 at 18:28 UTC
    I have had a similar problem with at least one of the DB implementations. I can't recall if it plain DB or one of the one of the others.

    The problem I found was that, to use your example, DB was not trying to open 'ECO' but 'ECO.pag' and 'ECO.dir'.

    IIRC the specification of DB defines an API but not a file format. There is no promise of compatability between inplementations.