[前][次][番号順一覧][スレッド一覧]

ruby-changes:23147

From: nobu <ko1@a...>
Date: Sat, 31 Mar 2012 14:23:15 +0900 (JST)
Subject: [ruby-changes:23147] nobu:r35197 (trunk): * hash.c (hash_default_value): extract from rb_hash_aref(), to be

nobu	2012-03-31 14:23:01 +0900 (Sat, 31 Mar 2012)

  New Revision: 35197

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35197

  Log:
    * hash.c (hash_default_value): extract from rb_hash_aref(), to be
      shared with rb_hash_shift(), so that overriding Hash#default
      will be respected.

  Modified files:
    trunk/ChangeLog
    trunk/hash.c
    trunk/test/ruby/test_hash.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 35196)
+++ ChangeLog	(revision 35197)
@@ -1,3 +1,9 @@
+Sat Mar 31 14:22:59 2012  Nobuyoshi Nakada  <nobu@r...>
+
+	* hash.c (hash_default_value): extract from rb_hash_aref(), to be
+	  shared with rb_hash_shift(), so that overriding Hash#default
+	  will be respected.
+
 Sat Mar 31 14:16:02 2012  Sokolov Yura (funny-falcon)  <funny.falcon@g...>
 
 	* hash.c: do not allocate st_table when it is not necessary.
Index: hash.c
===================================================================
--- hash.c	(revision 35196)
+++ hash.c	(revision 35197)
@@ -480,6 +480,20 @@
     return hash;
 }
 
+static VALUE
+hash_default_value(VALUE hash, VALUE key)
+{
+    if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
+	VALUE ifnone = RHASH_IFNONE(hash);
+	if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone;
+	if (key == Qundef) return Qnil;
+	return rb_funcall(ifnone, id_yield, 2, hash, key);
+    }
+    else {
+	return rb_funcall(hash, id_default, 1, key);
+    }
+}
+
 /*
  *  call-seq:
  *     hsh[key]    ->  value
@@ -500,13 +514,7 @@
     st_data_t val;
 
     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
-	if (!FL_TEST(hash, HASH_PROC_DEFAULT) &&
-	    rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
-	    return RHASH_IFNONE(hash);
-	}
-	else {
-	    return rb_funcall(hash, id_default, 1, key);
-	}
+	return hash_default_value(hash, key);
     }
     return (VALUE)val;
 }
@@ -865,12 +873,7 @@
 	    return rb_assoc_new(var.key, var.val);
 	}
     }
-    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
-	return rb_funcall(RHASH_IFNONE(hash), id_yield, 2, hash, Qnil);
-    }
-    else {
-	return RHASH_IFNONE(hash);
-    }
+    return hash_default_value(hash, Qnil);
 }
 
 static int
Index: test/ruby/test_hash.rb
===================================================================
--- test/ruby/test_hash.rb	(revision 35196)
+++ test/ruby/test_hash.rb	(revision 35197)
@@ -739,6 +739,14 @@
     h.each { assert_equal([1, 2], h.shift) }
   end
 
+  def test_shift_none
+    h = Hash.new {|hh, k| "foo"}
+    def h.default(k = nil)
+      default_proc.call(k).upcase
+    end
+    assert_equal("FOO", h.shift)
+  end
+
   def test_reject_bang2
     assert_equal({1=>2}, {1=>2,3=>4}.reject! {|k, v| k + v == 7 })
     assert_nil({1=>2,3=>4}.reject! {|k, v| k == 5 })

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]