@@ -1817,6 +1817,43 @@ mrb_hash_compact(mrb_state *mrb, mrb_value hash)
18171817return hash;
18181818}
181918191820+/*
1821+ * call-seq:
1822+ * hash.to_s -> string
1823+ * hash.inspect -> string
1824+ *
1825+ * Return the contents of this hash as a string.
1826+ */
1827+static mrb_value
1828+mrb_hash_to_s(mrb_state *mrb, mrb_value self)
1829+{
1830+mrb->c->ci->mid = MRB_SYM(inspect);
1831+mrb_value ret = mrb_str_new_lit(mrb, "{");
1832+int ai = mrb_gc_arena_save(mrb);
1833+if (mrb_inspect_recursive_p(mrb, self)) {
1834+mrb_str_cat_lit(mrb, ret, "...}");
1835+return ret;
1836+ }
1837+1838+mrb_int i = 0;
1839+struct RHash *h = mrb_hash_ptr(self);
1840+h_each(h, entry, {
1841+if (i++ > 0) mrb_str_cat_lit(mrb, ret, ", ");
1842+h_check_modified(mrb, h, {
1843+mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->key));
1844+ });
1845+mrb_gc_arena_restore(mrb, ai);
1846+mrb_str_cat_lit(mrb, ret, "=>");
1847+h_check_modified(mrb, h, {
1848+mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, entry->val));
1849+ });
1850+mrb_gc_arena_restore(mrb, ai);
1851+ });
1852+mrb_str_cat_lit(mrb, ret, "}");
1853+1854+return ret;
1855+}
1856+18201857void
18211858mrb_init_hash(mrb_state *mrb)
18221859{
@@ -1849,6 +1886,8 @@ mrb_init_hash(mrb_state *mrb)
18491886mrb_define_method(mrb, h, "store", mrb_hash_aset, MRB_ARGS_REQ(2)); /* 15.2.13.4.26 */
18501887mrb_define_method(mrb, h, "value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.27 */
18511888mrb_define_method(mrb, h, "values", mrb_hash_values, MRB_ARGS_NONE()); /* 15.2.13.4.28 */
1889+mrb_define_method(mrb, h, "to_s", mrb_hash_to_s, MRB_ARGS_NONE());
1890+mrb_define_method(mrb, h, "inspect", mrb_hash_to_s, MRB_ARGS_NONE());
18521891mrb_define_method(mrb, h, "rehash", mrb_hash_rehash, MRB_ARGS_NONE());
18531892mrb_define_method(mrb, h, "__merge", mrb_hash_merge_m, MRB_ARGS_REQ(1));
18541893mrb_define_method(mrb, h, "__compact", mrb_hash_compact, MRB_ARGS_NONE()); /* implementation of Hash#compact! */