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

ruby-changes:40456

From: nobu <ko1@a...>
Date: Wed, 11 Nov 2015 18:30:49 +0900 (JST)
Subject: [ruby-changes:40456] nobu:r52537 (trunk): sprintf.c: nil value is valid

nobu	2015-11-11 18:30:31 +0900 (Wed, 11 Nov 2015)

  New Revision: 52537

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

  Log:
    sprintf.c: nil value is valid
    
    * sprintf.c (rb_str_format): look up the key, then get default
      value and raise KeyError if the returned value is nil.
      [ruby-dev:49338] [Ruby trunk - Bug #11677]

  Modified files:
    trunk/ChangeLog
    trunk/hash.c
    trunk/internal.h
    trunk/sprintf.c
    trunk/test/ruby/test_sprintf.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 52536)
+++ ChangeLog	(revision 52537)
@@ -1,3 +1,9 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Nov 11 18:30:28 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* sprintf.c (rb_str_format): look up the key, then get default
+	  value and raise KeyError if the returned value is nil.
+	  [ruby-dev:49338] [Ruby trunk - Bug #11677]
+
 Wed Nov 11 17:38:24 2015  Nobuyoshi Nakada  <nobu@r...>
 
 	* vm_eval.c (local_var_list_add): skip internal local variable
Index: sprintf.c
===================================================================
--- sprintf.c	(revision 52536)
+++ sprintf.c	(revision 52537)
@@ -605,12 +605,20 @@ rb_str_format(int argc, const VALUE *arg https://github.com/ruby/ruby/blob/trunk/sprintf.c#L605
 		}
 		CHECKNAMEARG(start, len, enc);
 		get_hash(&hash, argc, argv);
-		sym = rb_cstr_intern(start + 1,
-				     len - 2 /* without parenthesis */,
-				     enc);
-		nextvalue = rb_hash_aref(hash, sym);
-		if (NIL_P(nextvalue) && !FL_TEST(hash, HASH_PROC_DEFAULT)) {
-		    rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
+		sym = rb_check_symbol_cstr(start + 1,
+					   len - 2 /* without parenthesis */,
+					   enc);
+		if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
+		if (nextvalue == Qundef) {
+		    if (NIL_P(sym)) {
+			sym = rb_cstr_intern(start + 1,
+					     len - 2 /* without parenthesis */,
+					     enc);
+		    }
+		    nextvalue = rb_hash_default_value(hash, sym);
+		    if (NIL_P(nextvalue)) {
+			rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
+		    }
 		}
 		if (term == '}') goto format_s;
 		p++;
Index: hash.c
===================================================================
--- hash.c	(revision 52536)
+++ hash.c	(revision 52537)
@@ -758,8 +758,8 @@ rb_hash_rehash(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L758
     return hash;
 }
 
-static VALUE
-hash_default_value(VALUE hash, VALUE key)
+VALUE
+rb_hash_default_value(VALUE hash, VALUE key)
 {
     if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
 	VALUE ifnone = RHASH_IFNONE(hash);
@@ -792,7 +792,7 @@ rb_hash_aref(VALUE hash, VALUE key) https://github.com/ruby/ruby/blob/trunk/hash.c#L792
     st_data_t val;
 
     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
-	return hash_default_value(hash, key);
+	return rb_hash_default_value(hash, key);
     }
     return (VALUE)val;
 }
@@ -1184,7 +1184,7 @@ rb_hash_shift(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1184
 	    }
 	}
     }
-    return hash_default_value(hash, Qnil);
+    return rb_hash_default_value(hash, Qnil);
 }
 
 static int
Index: internal.h
===================================================================
--- internal.h	(revision 52536)
+++ internal.h	(revision 52537)
@@ -828,6 +828,7 @@ void rb_gc_resurrect(VALUE ptr); https://github.com/ruby/ruby/blob/trunk/internal.h#L828
 /* hash.c */
 struct st_table *rb_hash_tbl_raw(VALUE hash);
 VALUE rb_hash_has_key(VALUE hash, VALUE key);
+VALUE rb_hash_default_value(VALUE hash, VALUE key);
 VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
 long rb_objid_hash(st_index_t index);
 st_table *rb_init_identtable(void);
Index: test/ruby/test_sprintf.rb
===================================================================
--- test/ruby/test_sprintf.rb	(revision 52536)
+++ test/ruby/test_sprintf.rb	(revision 52537)
@@ -415,4 +415,9 @@ class TestSprintf < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_sprintf.rb#L415
     assert_equal("hello world", "hello %{location}" % h)
     assert_equal("hello world", "hello %<location>s" % h)
   end
+
+  def test_named_with_nil
+    h = { key: nil, key2: "key2_val" }
+    assert_equal("key is , key2 is key2_val", "key is %{key}, key2 is %{key2}" % h)
+  end
 end

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

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