diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-27 04:52:21 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-02-27 04:52:21 +0000 |
commit | 3fc04d9361549d5bb15f869c22d7ce9591a0ac8c (patch) | |
tree | b160a4f2ed1605c1a4ef62d6c568ff807fda24c5 /ext/dbm | |
parent | 2fcd221fecabe3e6acaa21c54ae6d1ccbe8c0204 (diff) |
* ext/dbm/dbm.c (fdbm_select): 1.7 behavior.
* ext/gdbm/gdbm.c (fgdbm_select): ditto.
* ext/sdbm/sdbm.c (fsdbm_select): ditto.
* ext/dbm/dbm.c (fdbm_delete): adopt Hash#delete behavior.
* ext/sdbm/sdbm.c (fsdbm_delete): ditto.
* ext/gdbm/gdbm.c: need not to dup key to the block.
* ext/sdbm/sdbm.c : replace RuntimeError with SDBMError.
* eval.c (rb_f_missing): NoMethod error messages for true, false,
nil must respond visibility like for other objects.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2145 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/dbm')
-rw-r--r-- | ext/dbm/dbm.c | 76 | ||||
-rw-r--r-- | ext/dbm/testdbm.rb | 28 |
2 files changed, 83 insertions, 21 deletions
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c index 55e207c49a..f81f7efcb1 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -32,7 +32,7 @@ struct dbmdata { static void closed_dbm() { - rb_raise(rb_eRuntimeError, "closed DBM file"); + rb_raise(rb_eDBMError, "closed DBM file"); } #define GetDBM(obj, dbmp) {\ @@ -51,7 +51,18 @@ free_dbm(dbmp) } } -static VALUE fdbm_close _((VALUE)); +static VALUE +fdbm_close(obj) + VALUE obj; +{ + struct dbmdata *dbmp; + + GetDBM(obj, dbmp); + dbm_close(dbmp->di_dbm); + dbmp->di_dbm = 0; + + return Qnil; +} static VALUE fdbm_s_new(argc, argv, klass) @@ -130,19 +141,6 @@ fdbm_s_open(argc, argv, klass) } static VALUE -fdbm_close(obj) - VALUE obj; -{ - struct dbmdata *dbmp; - - GetDBM(obj, dbmp); - dbm_close(dbmp->di_dbm); - dbmp->di_dbm = 0; - - return Qnil; -} - -static VALUE fdbm_fetch(obj, keystr, ifnone) VALUE obj, keystr, ifnone; { @@ -230,12 +228,52 @@ fdbm_indexes(argc, argv, obj) } static VALUE +fdbm_select(argc, argv, obj) + int argc; + VALUE *argv; + VALUE obj; +{ + VALUE new = rb_ary_new2(argc); + int i; + + if (rb_block_given_p()) { + datum key, val; + DBM *dbm; + struct dbmdata *dbmp; + VALUE keystr, valstr; + + if (argc > 0) { + rb_raise(rb_eArgError, "wrong number arguments(%d for 0)", argc); + } + GetDBM(obj, dbmp); + dbm = dbmp->di_dbm; + + for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { + VALUE assoc; + val = dbm_fetch(dbm, key); + assoc = rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize), + rb_tainted_str_new(val.dptr, val.dsize)); + if (RTEST(rb_yield(assoc))) + rb_ary_push(new, assoc); + } + } + else { + for (i=0; i<argc; i++) { + rb_ary_push(new, fdbm_fetch(obj, argv[i])); + } + } + + return new; +} + +static VALUE fdbm_delete(obj, keystr) VALUE obj, keystr; { datum key, value; struct dbmdata *dbmp; DBM *dbm; + VALUE valstr; rb_secure(4); StringValue(keystr); @@ -247,10 +285,13 @@ fdbm_delete(obj, keystr) value = dbm_fetch(dbm, key); if (value.dptr == 0) { - if (rb_block_given_p()) rb_yield(keystr); + if (rb_block_given_p()) return rb_yield(keystr); return Qnil; } + /* need to save value before dbm_delete() */ + valstr = rb_tainted_str_new(value.dptr, value.dsize); + if (dbm_delete(dbm, key)) { dbmp->di_size = -1; rb_raise(rb_eDBMError, "dbm_delete failed"); @@ -258,7 +299,7 @@ fdbm_delete(obj, keystr) else if (dbmp->di_size >= 0) { dbmp->di_size--; } - return obj; + return valstr; } static VALUE @@ -691,6 +732,7 @@ Init_dbm() rb_define_method(rb_cDBM, "index", fdbm_index, 1); rb_define_method(rb_cDBM, "indexes", fdbm_indexes, -1); rb_define_method(rb_cDBM, "indices", fdbm_indexes, -1); + rb_define_method(rb_cDBM, "select", fdbm_select, -1); rb_define_method(rb_cDBM, "length", fdbm_length, 0); rb_define_method(rb_cDBM, "size", fdbm_length, 0); rb_define_method(rb_cDBM, "empty?", fdbm_empty_p, 0); diff --git a/ext/dbm/testdbm.rb b/ext/dbm/testdbm.rb index c6b26e0cdf..0be627d346 100644 --- a/ext/dbm/testdbm.rb +++ b/ext/dbm/testdbm.rb @@ -165,7 +165,7 @@ class TestDBM < RUNIT::TestCase assert_nil(dbm.close) # closed DBM file - assert_exception(RuntimeError) { dbm.close } + assert_exception(DBMError) { dbm.close } end def test_aref @@ -245,6 +245,25 @@ class TestDBM < RUNIT::TestCase assert_equals(values.reverse, @dbm.indexes(*keys.reverse)) end + def test_select + keys = %w(foo bar baz) + values = %w(FOO BAR BAZ) + @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values + assert_equals(values.reverse, @dbm.select(*keys.reverse)) + end + + def test_select_with_block + keys = %w(foo bar baz) + values = %w(FOO BAR BAZ) + @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values + ret = @dbm.select {|k,v| + assert_equals(k.upcase, v) + k != "bar" + } + assert_equals([['baz', 'BAZ'], ['foo', 'FOO']], + ret.sort) + end + def test_length num = 10 assert_equals(0, @dbm.size) @@ -377,7 +396,7 @@ class TestDBM < RUNIT::TestCase @dbm[keys[0]], @dbm[keys[1]], @dbm[keys[2]] = values - assert_equals(@dbm, @dbm.delete(key)) + assert_equals('BAR', @dbm.delete(key)) assert_nil(@dbm[key]) assert_equals(2, @dbm.size) @@ -394,12 +413,13 @@ class TestDBM < RUNIT::TestCase def test_delete_with_block key = 'no called block' @dbm[key] = 'foo' - assert_equals(@dbm, @dbm.delete(key) {|k| k.replace 'called block'}) + assert_equals('foo', @dbm.delete(key) {|k| k.replace 'called block'}) assert_equals('no called block', key) assert_equals(0, @dbm.size) key = 'no called block' - assert_nil(@dbm.delete(key) {|k| k.replace 'called block'}) + assert_equals(:blockval, + @dbm.delete(key) {|k| k.replace 'called block'; :blockval}) assert_equals('called block', key) assert_equals(0, @dbm.size) end |