能條といいます.

dbm,gdbm,sdbm に共通のバグで,データベースを閉じた後,

  + DBM#[]=
  + DBM#length
  + DBM#empty?

のいずれかを行うと Ruby が落ちます.

以下サンプルコードとパッチです.
----
require "dbm"
d = DBM.open("test")
d.close

p "-- []= --"
d['foobar'] = 'FB' #=> X-O

p "-- length --"
d.length           #=> X-O

p "-- empty? --"
d.empty?           #=> X-O

p "-- end --"
----

----
Satoshi Nojo
eMail: nojo / t-samukawa.or.jp
HomePage:
  http://www.geocities.co.jp/SiliconValley-PaloAlto/1409/ruby/

# Ruby はバグが見つかるとすぐに修正されていて,
# その修正の早さにいつも驚いています.


--- ruby-1.4/ext/dbm/dbm.c.orig Mon Apr 10 14:48:40 2000 +++ ruby-1.4/ext/dbm/dbm.c Fri Jun 16 03:17:36 2000 @@ -98,8 +98,7 @@ { struct dbmdata *dbmp; - Data_Get_Struct(obj, struct dbmdata, dbmp); - if (dbmp->di_dbm == 0) closed_dbm(); + GetDBM(obj, dbmp); dbm_close(dbmp->di_dbm); dbmp->di_dbm = 0; @@ -328,7 +327,7 @@ val.dptr = RSTRING(valstr)->ptr; val.dsize = RSTRING(valstr)->len; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); dbmp->di_size = -1; dbm = dbmp->di_dbm; if (dbm_store(dbm, key, val, DBM_REPLACE)) { @@ -351,7 +350,7 @@ DBM *dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size); dbm = dbmp->di_dbm; @@ -372,7 +371,7 @@ DBM *dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size < 0) { dbm = dbmp->di_dbm; --- ruby-1.4/ext/gdbm/gdbm.c.orig Mon Apr 10 14:48:42 2000 +++ ruby-1.4/ext/gdbm/gdbm.c Fri Jun 16 02:41:50 2000 @@ -99,8 +99,7 @@ { struct dbmdata *dbmp; - Data_Get_Struct(obj, struct dbmdata, dbmp); - if (dbmp->di_dbm == 0) closed_dbm(); + GetDBM(obj, dbmp); gdbm_close(dbmp->di_dbm); dbmp->di_dbm = 0; @@ -330,7 +329,7 @@ val.dptr = RSTRING(valstr)->ptr; val.dsize = RSTRING(valstr)->len; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); dbmp->di_size = -1; dbm = dbmp->di_dbm; if (gdbm_store(dbm, key, val, GDBM_REPLACE)) { @@ -350,7 +349,7 @@ GDBM_FILE dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size); dbm = dbmp->di_dbm; @@ -371,7 +370,7 @@ GDBM_FILE dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size < 0) { dbm = dbmp->di_dbm; --- ruby-1.4/ext/sdbm/init.c.orig Fri Aug 13 14:37:50 1999 +++ ruby-1.4/ext/sdbm/init.c Fri Jun 16 02:43:28 2000 @@ -95,8 +95,7 @@ { struct dbmdata *dbmp; - Data_Get_Struct(obj, struct dbmdata, dbmp); - if (dbmp->di_dbm == 0) closed_sdbm(); + GetDBM(obj, dbmp); sdbm_close(dbmp->di_dbm); dbmp->di_dbm = 0; @@ -325,7 +324,7 @@ val.dptr = RSTRING(valstr)->ptr; val.dsize = RSTRING(valstr)->len; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); dbmp->di_size = -1; dbm = dbmp->di_dbm; if (sdbm_store(dbm, key, val, DBM_REPLACE)) { @@ -348,7 +347,7 @@ DBM *dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size); dbm = dbmp->di_dbm; @@ -369,7 +368,7 @@ DBM *dbm; int i = 0; - Data_Get_Struct(obj, struct dbmdata, dbmp); + GetDBM(obj, dbmp); if (dbmp->di_size < 0) { dbm = dbmp->di_dbm;