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] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52537 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
9cf1136481
commit
56e3b49304
@ -1,3 +1,9 @@
|
|||||||
|
Wed Nov 11 18:30:28 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* 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@ruby-lang.org>
|
Wed Nov 11 17:38:24 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* vm_eval.c (local_var_list_add): skip internal local variable
|
* vm_eval.c (local_var_list_add): skip internal local variable
|
||||||
|
8
hash.c
8
hash.c
@ -758,8 +758,8 @@ rb_hash_rehash(VALUE hash)
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
VALUE
|
||||||
hash_default_value(VALUE hash, VALUE key)
|
rb_hash_default_value(VALUE hash, VALUE key)
|
||||||
{
|
{
|
||||||
if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
|
if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
|
||||||
VALUE ifnone = RHASH_IFNONE(hash);
|
VALUE ifnone = RHASH_IFNONE(hash);
|
||||||
@ -792,7 +792,7 @@ rb_hash_aref(VALUE hash, VALUE key)
|
|||||||
st_data_t val;
|
st_data_t val;
|
||||||
|
|
||||||
if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &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;
|
return (VALUE)val;
|
||||||
}
|
}
|
||||||
@ -1184,7 +1184,7 @@ rb_hash_shift(VALUE hash)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return hash_default_value(hash, Qnil);
|
return rb_hash_default_value(hash, Qnil);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -828,6 +828,7 @@ void rb_gc_resurrect(VALUE ptr);
|
|||||||
/* hash.c */
|
/* hash.c */
|
||||||
struct st_table *rb_hash_tbl_raw(VALUE hash);
|
struct st_table *rb_hash_tbl_raw(VALUE hash);
|
||||||
VALUE rb_hash_has_key(VALUE hash, VALUE key);
|
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);
|
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
|
||||||
long rb_objid_hash(st_index_t index);
|
long rb_objid_hash(st_index_t index);
|
||||||
st_table *rb_init_identtable(void);
|
st_table *rb_init_identtable(void);
|
||||||
|
20
sprintf.c
20
sprintf.c
@ -605,12 +605,20 @@ rb_str_format(int argc, const VALUE *argv, VALUE fmt)
|
|||||||
}
|
}
|
||||||
CHECKNAMEARG(start, len, enc);
|
CHECKNAMEARG(start, len, enc);
|
||||||
get_hash(&hash, argc, argv);
|
get_hash(&hash, argc, argv);
|
||||||
sym = rb_cstr_intern(start + 1,
|
sym = rb_check_symbol_cstr(start + 1,
|
||||||
len - 2 /* without parenthesis */,
|
len - 2 /* without parenthesis */,
|
||||||
enc);
|
enc);
|
||||||
nextvalue = rb_hash_aref(hash, sym);
|
if (!NIL_P(sym)) nextvalue = rb_hash_lookup2(hash, sym, Qundef);
|
||||||
if (NIL_P(nextvalue) && !FL_TEST(hash, HASH_PROC_DEFAULT)) {
|
if (nextvalue == Qundef) {
|
||||||
rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start);
|
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;
|
if (term == '}') goto format_s;
|
||||||
p++;
|
p++;
|
||||||
|
@ -415,4 +415,9 @@ class TestSprintf < Test::Unit::TestCase
|
|||||||
assert_equal("hello world", "hello %{location}" % h)
|
assert_equal("hello world", "hello %{location}" % h)
|
||||||
assert_equal("hello world", "hello %<location>s" % h)
|
assert_equal("hello world", "hello %<location>s" % h)
|
||||||
end
|
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
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user