Skip to content

Commit

Permalink
* hash.c (rb_hash_assoc): revert r42224. table->type->compare is
Browse files Browse the repository at this point in the history
  called only if hashes are matched.

* test/ruby/test_hash.rb: add a test to check using #== to compare.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42232 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information
glass committed Jul 29, 2013
1 parent 6281167 commit 8caa801
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 44 deletions.
7 changes: 7 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
Mon Jul 29 20:14:24 2013 Masaki Matsushita <glass.saga@gmail.com>

* hash.c (rb_hash_assoc): revert r42224. table->type->compare is
called only if hashes are matched.

* test/ruby/test_hash.rb: add a test to check using #== to compare.

Mon Jul 29 17:00:31 2013 Nobuyoshi Nakada <nobu@ruby-lang.org>

* parse.y (yycompile): store file name as String to keep the encoding.
Expand Down
58 changes: 14 additions & 44 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -2123,34 +2123,15 @@ rb_hash_merge(VALUE hash1, VALUE hash2)
}

static int
assoc_cmp(VALUE a, VALUE b)
assoc_i(VALUE key, VALUE val, VALUE arg)
{
return !RTEST(rb_equal(a, b));
}

struct lookup2_arg {
VALUE hash;
VALUE key;
};

static VALUE
lookup2_call(VALUE arg)
{
struct lookup2_arg *p = (struct lookup2_arg *)arg;
return rb_hash_lookup2(p->hash, p->key, Qundef);
}

struct reset_hash_type_arg {
VALUE hash;
const struct st_hash_type *orighash;
};
VALUE *args = (VALUE *)arg;

static VALUE
reset_hash_type(VALUE arg)
{
struct reset_hash_type_arg *p = (struct reset_hash_type_arg *)arg;
RHASH(p->hash)->ntbl->type = p->orighash;
return Qundef;
if (RTEST(rb_equal(args[0], key))) {
args[1] = rb_assoc_new(key, val);
return ST_STOP;
}
return ST_CONTINUE;
}

/*
Expand All @@ -2168,25 +2149,14 @@ reset_hash_type(VALUE arg)
*/

VALUE
rb_hash_assoc(VALUE hash, VALUE key)
rb_hash_assoc(VALUE hash, VALUE obj)
{
VALUE value;
st_table *table = hash_tbl(hash);
struct lookup2_arg arg;
struct reset_hash_type_arg ensure_arg;
const struct st_hash_type *orighash = table->type;
struct st_hash_type assochash;

assochash.compare = assoc_cmp;
assochash.hash = orighash->hash;
table->type = &assochash;
arg.hash = hash;
arg.key = key;
ensure_arg.hash = hash;
ensure_arg.orighash = orighash;
value = rb_ensure(lookup2_call, (VALUE)&arg, reset_hash_type, (VALUE)&ensure_arg);
if (value == Qundef) return Qnil;
return rb_assoc_new(key, value);
VALUE args[2];

args[0] = obj;
args[1] = Qnil;
rb_hash_foreach(hash, assoc_i, (VALUE)args);
return args[1];
}

static int
Expand Down
1 change: 1 addition & 0 deletions test/ruby/test_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -876,6 +876,7 @@ def test_merge
def test_assoc
assert_equal([3,4], {1=>2, 3=>4, 5=>6}.assoc(3))
assert_nil({1=>2, 3=>4, 5=>6}.assoc(4))
assert_equal([1.0,1], {1.0=>1}.assoc(1))
end

def test_rassoc
Expand Down

0 comments on commit 8caa801

Please sign in to comment.