diff --git a/mrblib/hash.rb b/mrblib/hash.rb index 46758d8b7..90b673642 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -195,30 +195,6 @@ class Hash h end - # internal method for Hash inspection - def _inspect(recur_list) - return "{}" if self.size == 0 - return "{...}" if recur_list[self.object_id] - recur_list[self.object_id] = true - ary=[] - keys=self.keys - vals=self.values - size=keys.size - i=0 - while i" + vals[i]._inspect(recur_list)) - i+=1 - end - "{"+ary.join(", ")+"}" - end - ## - # Return the contents of this hash as a string. - # - def inspect - self._inspect({}) - end - alias to_s inspect - ## # call-seq: # hsh.reject! {| key, value | block } -> hsh or nil diff --git a/src/hash.c b/src/hash.c index ee3c43d5c..c165fc244 100644 --- a/src/hash.c +++ b/src/hash.c @@ -1817,6 +1817,43 @@ mrb_hash_compact(mrb_state *mrb, mrb_value hash) return hash; } +/* + * call-seq: + * hash.to_s -> string + * hash.inspect -> string + * + * Return the contents of this hash as a string. + */ +static mrb_value +mrb_hash_to_s(mrb_state *mrb, mrb_value self) +{ + mrb->c->ci->mid = MRB_SYM(inspect); + mrb_value ret = mrb_str_new_lit(mrb, "{"); + int ai = mrb_gc_arena_save(mrb); + if (mrb_inspect_recursive_p(mrb, self)) { + mrb_str_cat_lit(mrb, ret, "...}"); + return ret; + } + + mrb_int i = 0; + struct RHash *h = mrb_hash_ptr(self); + h_each(h, entry, { + if (i++ > 0) mrb_str_cat_lit(mrb, ret, ", "); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->key)); + }); + mrb_gc_arena_restore(mrb, ai); + mrb_str_cat_lit(mrb, ret, "=>"); + h_check_modified(mrb, h, { + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->val)); + }); + mrb_gc_arena_restore(mrb, ai); + }); + mrb_str_cat_lit(mrb, ret, "}"); + + return ret; +} + void mrb_init_hash(mrb_state *mrb) { @@ -1849,6 +1886,8 @@ mrb_init_hash(mrb_state *mrb) mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */ mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */ mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */ + mrb_define_method(mrb, h, "to_s", mrb_hash_to_s, MRB_ARGS_NONE()); + mrb_define_method(mrb, h, "inspect", mrb_hash_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE()); mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1)); mrb_define_method(mrb, h, "__compact", mrb_hash_compact, MRB_ARGS_NONE()); /* implementation of Hash#compact! */