summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--hash.c58
-rw-r--r--test/ruby/test_hash.rb1
3 files changed, 22 insertions, 44 deletions
diff --git a/ChangeLog b/ChangeLog
index b0aa059095e..19b761acfe2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/hash.c b/hash.c
index 5a8dd9b1fa8..b9a8cb17387 100644
--- a/hash.c
+++ b/hash.c
@@ -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;
}
/*
@@ -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
diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb
index e8b8ef040c8..5694d2f01e2 100644
--- a/test/ruby/test_hash.rb
+++ b/test/ruby/test_hash.rb
@@ -876,6 +876,7 @@ class TestHash < Test::Unit::TestCase
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