зеркало из https://github.com/github/ruby.git
Hash#inspect with colon style
This commit is contained in:
Родитель
2c0149d330
Коммит
a8a0591253
51
hash.c
51
hash.c
|
@ -3405,20 +3405,65 @@ rb_hash_to_a(VALUE hash)
|
|||
return ary;
|
||||
}
|
||||
|
||||
static bool
|
||||
symbol_key_needs_quote(VALUE str)
|
||||
{
|
||||
long len = RSTRING_LEN(str);
|
||||
if (len == 0 || !rb_str_symname_p(str)) return true;
|
||||
const char *s = RSTRING_PTR(str);
|
||||
char first = s[0];
|
||||
if (first == '@' || first == '$' || first == '!') return true;
|
||||
if (!at_char_boundary(s, s + len - 1, RSTRING_END(str), rb_enc_get(str))) return false;
|
||||
switch (s[len - 1]) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '*':
|
||||
case '/':
|
||||
case '`':
|
||||
case '%':
|
||||
case '^':
|
||||
case '&':
|
||||
case '|':
|
||||
case ']':
|
||||
case '<':
|
||||
case '=':
|
||||
case '>':
|
||||
case '~':
|
||||
case '@':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
inspect_i(VALUE key, VALUE value, VALUE str)
|
||||
{
|
||||
VALUE str2;
|
||||
|
||||
str2 = rb_inspect(key);
|
||||
bool is_symbol = SYMBOL_P(key);
|
||||
bool quote = false;
|
||||
if (is_symbol) {
|
||||
str2 = rb_sym2str(key);
|
||||
quote = symbol_key_needs_quote(str2);
|
||||
}
|
||||
else {
|
||||
str2 = rb_inspect(key);
|
||||
}
|
||||
if (RSTRING_LEN(str) > 1) {
|
||||
rb_str_buf_cat_ascii(str, ", ");
|
||||
}
|
||||
else {
|
||||
rb_enc_copy(str, str2);
|
||||
}
|
||||
rb_str_buf_append(str, str2);
|
||||
rb_str_buf_cat_ascii(str, "=>");
|
||||
if (quote) {
|
||||
rb_str_buf_append(str, rb_str_inspect(str2));
|
||||
}
|
||||
else {
|
||||
rb_str_buf_append(str, str2);
|
||||
}
|
||||
|
||||
rb_str_buf_cat_ascii(str, is_symbol ? ": " : " => ");
|
||||
str2 = rb_inspect(value);
|
||||
rb_str_buf_append(str, str2);
|
||||
|
||||
|
|
|
@ -869,6 +869,33 @@ class TestHash < Test::Unit::TestCase
|
|||
$, = nil
|
||||
end
|
||||
|
||||
def test_inspect
|
||||
no_quote = '{a: 1, a!: 1, a?: 1}'
|
||||
quote0 = '{"": 1}'
|
||||
quote1 = '{"0": 1, "!": 1, "%": 1, "&": 1, "*": 1, "+": 1, "-": 1, "/": 1, "<": 1, ">": 1, "^": 1, "`": 1, "|": 1, "~": 1}'
|
||||
quote2 = '{"@a": 1, "$a": 1, "+@": 1, "a=": 1, "[]": 1}'
|
||||
quote3 = '{"a\"b": 1, "@@a": 1, "<=>": 1, "===": 1, "[]=": 1}'
|
||||
assert_equal(no_quote, eval(no_quote).inspect)
|
||||
assert_equal(quote0, eval(quote0).inspect)
|
||||
assert_equal(quote1, eval(quote1).inspect)
|
||||
assert_equal(quote2, eval(quote2).inspect)
|
||||
assert_equal(quote3, eval(quote3).inspect)
|
||||
begin
|
||||
enc = Encoding.default_external
|
||||
Encoding.default_external = Encoding::ASCII
|
||||
utf8_ascii_hash = '{"\\u3042": 1}'
|
||||
assert_equal(eval(utf8_ascii_hash).inspect, utf8_ascii_hash)
|
||||
Encoding.default_external = Encoding::UTF_8
|
||||
utf8_hash = "{\u3042: 1}"
|
||||
assert_equal(eval(utf8_hash).inspect, utf8_hash)
|
||||
Encoding.default_external = Encoding::Windows_31J
|
||||
sjis_hash = "{\x87]: 1}".force_encoding('sjis')
|
||||
assert_equal(eval(sjis_hash).inspect, sjis_hash)
|
||||
ensure
|
||||
Encoding.default_external = enc
|
||||
end
|
||||
end
|
||||
|
||||
def test_update
|
||||
h1 = @cls[ 1 => 2, 2 => 3, 3 => 4 ]
|
||||
h2 = @cls[ 2 => 'two', 4 => 'four' ]
|
||||
|
|
Загрузка…
Ссылка в новой задаче