mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
2fcd221fec
commit
3fc04d9361
9 changed files with 398 additions and 194 deletions
|
|
@ -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)
|
||||
|
|
@ -129,19 +140,6 @@ fdbm_s_open(argc, argv, klass)
|
|||
return obj;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -229,6 +227,45 @@ fdbm_indexes(argc, argv, obj)
|
|||
return new;
|
||||
}
|
||||
|
||||
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;
|
||||
|
|
@ -236,6 +273,7 @@ fdbm_delete(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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue