Mailing List Archive

fix for exists() with tied GDBM_File
exists($tiedhash{$key}) doesn't work with GDBM_File:

use GDBM_File;

my %d;
tie %d, 'GDBM_File', "test.gdbm", GDBM_NEWDB, 0600;

$d{foo} = 'bar';
print exists($d{foo}), "\n";


$ perl e.pl
GDBM_File doesn't define an EXISTS method at e.pl line 7
$


Renaming "exists" to "EXISTS" in GDBM_File.xs fixes it:

--- /d2/src/perl5.001m/ext/GDBM_File/GDBM_File.xs Thu Jun 22 09:54:54 1995
+++ GDBM_File.xs Wed Sep 13 11:00:45 1995
@@ -16,6 +16,7 @@
#define gdbm_DELETE(db,key) gdbm_delete(db,key)
#define gdbm_FIRSTKEY(db) gdbm_firstkey(db)
#define gdbm_NEXTKEY(db,key) gdbm_nextkey(db,key)
+#define gdbm_EXISTS(db,key) gdbm_exists(db,key)

typedef datum gdatum;

@@ -232,7 +233,7 @@
GDBM_File db

int
-gdbm_exists(db, key)
+gdbm_EXISTS(db, key)
GDBM_File db
datum key


But this raises another question, how do I access methods in GDBM_File
if they aren't tie methods?

tie %d, 'GDBM_File', "test.gdbm", GDBM_NEWDB, 0600;

What I have is %d, which is tied internally somewhere to a GDBM_File
object. If I want to call another function in the GDBM_File package,
like sync() or reorganize(), how do I get to the object?

-Andrew
Re: fix for exists() with tied GDBM_File [ In reply to ]
: But this raises another question, how do I access methods in GDBM_File
: if they aren't tie methods?
:
: tie %d, 'GDBM_File', "test.gdbm", GDBM_NEWDB, 0600;
:
: What I have is %d, which is tied internally somewhere to a GDBM_File
: object. If I want to call another function in the GDBM_File package,
: like sync() or reorganize(), how do I get to the object?

There's no easy way currently to get back to the object through the
tied variable. The tie returns the associated object, but if a lower
level routine throws that info away, it's gone.

There really ought to be a way to get at the associated object, since
the info is obvious stored with the hash, and one could conceivable have
large numbers of tied hashes for which one wouldn't want to keep track
of all the associated objects.

Larry
Re: fix for exists() with tied GDBM_File [ In reply to ]
>What I have is %d, which is tied internally somewhere to a GDBM_File
>object. If I want to call another function in the GDBM_File package,
>like sync() or reorganize(), how do I get to the object?
>
>-Andrew
>

Tie returns a reference to the object %d is tied to. So I'd try (untested)

$ref = tie %d, 'GDBM_File', "test.gdbm", GDBM_NEWDB, 0600;
[...]
$ref->reorganize;

Hope, that helps, hope that works,
andreas
Re: fix for exists() with tied GDBM_File [ In reply to ]
On Wed, 13 Sep 1995, Andrew Wilcox wrote:

> Renaming "exists" to "EXISTS" in GDBM_File.xs fixes it:

--- but breaks those scripts using the GDBM_File::gdbm_exists()
function directly. I guess you need both gdbm_exists and gdbm_EXISTS
to be accessible.

Andy Dougherty doughera@lafcol.lafayette.edu
Re: fix for exists() with tied GDBM_File [ In reply to ]
> --- but breaks those scripts using the GDBM_File::gdbm_exists()
> function directly.

That would be GDBM_File::exists(), I believe.

GDBM_File.xs uses a hack to get the uppercase names:

#define gdbm_FETCH(db,key) gdbm_fetch(db,key)
. . .
gdatum
gdbm_FETCH(db, key)

The C compiler sees the #define, but the xs compiler doesn't, so Perl
sees FETCH as the name of the function. Took me a while to figure
that one out.

Maybe the .xs should concentrate on providing an interface to the
library, and the .pm should provide the tie functions. (Which only by
coincidence happens to take the same arguments).

*{"GDBM_File::FETCH"} = \&fetch;

Or is that going to mess up autoloading?

-Andrew
Re: fix for exists() with tied GDBM_File [ In reply to ]
: Maybe the .xs should concentrate on providing an interface to the
: library, and the .pm should provide the tie functions. (Which only by
: coincidence happens to take the same arguments).
:
: *{"GDBM_File::FETCH"} = \&fetch;

Why would you want to do the name mapping at run time when it can be
done easily at compile time? Starting up Perl scripts is already
plenty slow. It would also make for duplication in the symbol table.

Larry
Re: fix for exists() with tied GDBM_File [ In reply to ]
On Wed, 13 Sep 1995, Larry Wall wrote:

> : But this raises another question, how do I access methods in GDBM_File
> : if they aren't tie methods?
> :
> : tie %d, 'GDBM_File', "test.gdbm", GDBM_NEWDB, 0600;
> :
> : What I have is %d, which is tied internally somewhere to a GDBM_File
> : object. If I want to call another function in the GDBM_File package,
> : like sync() or reorganize(), how do I get to the object?
>
> There's no easy way currently to get back to the object through the
> tied variable. The tie returns the associated object, but if a lower
> level routine throws that info away, it's gone.
>
> There really ought to be a way to get at the associated object, since
> the info is obvious stored with the hash, and one could conceivable have
> large numbers of tied hashes for which one wouldn't want to keep track
> of all the associated objects.

For a tied hash, you could always use a FETCH of "__internal__" or
somesuch to return a reference to the actual hash. But this is definite
name-space pollution, and a nasty bug for the unwary.

> Larry

--
Kenneth Albanowski (kjahds@kjahds.com, CIS: 70705,126)
Re: fix for exists() with tied GDBM_File [ In reply to ]
Re: fix for exists() with tied GDBM_File [ In reply to ]
On Wed, 13 Sep 1995 08:49:36 PDT, Larry Wall wrote:
>: What I have is %d, which is tied internally somewhere to a GDBM_File
>: object. If I want to call another function in the GDBM_File package,
>: like sync() or reorganize(), how do I get to the object?
>
>There's no easy way currently to get back to the object through the
>tied variable. The tie returns the associated object, but if a lower
>level routine throws that info away, it's gone.
>
>There really ought to be a way to get at the associated object, since
>the info is obvious stored with the hash, and one could conceivable have
>large numbers of tied hashes for which one wouldn't want to keep track
>of all the associated objects.
>
>Larry
>

I believe it was Paul Marquess who posted a patch to create a "tied()"
function that does this. I subsequently made this into a (rather trivial)
XS sub for my own use. I can post that here if there is sufficient interest.

- Sarathy.
gsar@engin.umich.edu