Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

* 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.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
  • Loading branch information...
commit 160d02d830d93316a8b4afd54138c1a8bfb8a6b3 1 parent 15ca66e
Nobuyoshi Nakada authored
6  ChangeLog
... ...
@@ -1,3 +1,9 @@
  1
+Sat Mar 31 14:22:59 2012  Nobuyoshi Nakada  <nobu@ruby-lang.org>
  2
+
  3
+	* hash.c (hash_default_value): extract from rb_hash_aref(), to be
  4
+	  shared with rb_hash_shift(), so that overriding Hash#default
  5
+	  will be respected.
  6
+
1 7
 Sat Mar 31 14:16:02 2012  Sokolov Yura (funny-falcon)  <funny.falcon@gmail.com>
2 8
 
3 9
 	* hash.c: do not allocate st_table when it is not necessary.
29  hash.c
@@ -480,6 +480,20 @@ rb_hash_rehash(VALUE hash)
480 480
     return hash;
481 481
 }
482 482
 
  483
+static VALUE
  484
+hash_default_value(VALUE hash, VALUE key)
  485
+{
  486
+    if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
  487
+	VALUE ifnone = RHASH_IFNONE(hash);
  488
+	if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone;
  489
+	if (key == Qundef) return Qnil;
  490
+	return rb_funcall(ifnone, id_yield, 2, hash, key);
  491
+    }
  492
+    else {
  493
+	return rb_funcall(hash, id_default, 1, key);
  494
+    }
  495
+}
  496
+
483 497
 /*
484 498
  *  call-seq:
485 499
  *     hsh[key]    ->  value
@@ -500,13 +514,7 @@ rb_hash_aref(VALUE hash, VALUE key)
500 514
     st_data_t val;
501 515
 
502 516
     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
503  
-	if (!FL_TEST(hash, HASH_PROC_DEFAULT) &&
504  
-	    rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
505  
-	    return RHASH_IFNONE(hash);
506  
-	}
507  
-	else {
508  
-	    return rb_funcall(hash, id_default, 1, key);
509  
-	}
  517
+	return hash_default_value(hash, key);
510 518
     }
511 519
     return (VALUE)val;
512 520
 }
@@ -865,12 +873,7 @@ rb_hash_shift(VALUE hash)
865 873
 	    return rb_assoc_new(var.key, var.val);
866 874
 	}
867 875
     }
868  
-    if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
869  
-	return rb_funcall(RHASH_IFNONE(hash), id_yield, 2, hash, Qnil);
870  
-    }
871  
-    else {
872  
-	return RHASH_IFNONE(hash);
873  
-    }
  876
+    return hash_default_value(hash, Qnil);
874 877
 }
875 878
 
876 879
 static int
8  test/ruby/test_hash.rb
@@ -739,6 +739,14 @@ def test_shift2
739 739
     h.each { assert_equal([1, 2], h.shift) }
740 740
   end
741 741
 
  742
+  def test_shift_none
  743
+    h = Hash.new {|hh, k| "foo"}
  744
+    def h.default(k = nil)
  745
+      default_proc.call(k).upcase
  746
+    end
  747
+    assert_equal("FOO", h.shift)
  748
+  end
  749
+
742 750
   def test_reject_bang2
743 751
     assert_equal({1=>2}, {1=>2,3=>4}.reject! {|k, v| k + v == 7 })
744 752
     assert_nil({1=>2,3=>4}.reject! {|k, v| k == 5 })

0 notes on commit 160d02d

Please sign in to comment.
Something went wrong with that request. Please try again.