From 6ae6b63aafbf64abd895aaeb84d80269a441a680 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 22 Jun 2023 12:53:51 +0900 Subject: [PATCH] mruby-struct: add recursive inspect check instead of _inspect hack --- mrbgems/mruby-struct/mrblib/struct.rb | 29 ----------------- mrbgems/mruby-struct/src/struct.c | 45 +++++++++++++++++++++++++++ mrbgems/mruby-struct/test/struct.rb | 2 +- 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/mrbgems/mruby-struct/mrblib/struct.rb b/mrbgems/mruby-struct/mrblib/struct.rb index f80c54518..20d9bde86 100644 --- a/mrbgems/mruby-struct/mrblib/struct.rb +++ b/mrbgems/mruby-struct/mrblib/struct.rb @@ -45,35 +45,6 @@ class Struct ary end - def _inspect(recur_list) - return "#" if recur_list[self.object_id] - recur_list[self.object_id] = true - name = self.class.to_s - if name[0] == "#" - str = "#" - end - - ## - # call-seq: - # struct.to_s -> string - # struct.inspect -> string - # - # Describe the contents of this struct in a string. - # - # 15.2.18.4.10(x) - # - def inspect - self._inspect({}) - end - ## # 15.2.18.4.11(x) # diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 2b824320d..4f6dadcfb 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -634,6 +634,49 @@ mrb_struct_values_at(mrb_state *mrb, mrb_value self) return mrb_get_values_at(mrb, self, RSTRUCT_LEN(self), argc, argv, struct_aref_int); } +/* + * call-seq: + * struct.to_s -> string + * struct.inspect -> string + * + * Returns a string representation of Data + */ +static mrb_value +mrb_struct_to_s(mrb_state *mrb, mrb_value self) +{ + mrb_value members, ret, cname; + mrb_value *mems; + mrb_int mlen; + + mrb->c->ci->mid = MRB_SYM(inspect); + ret = mrb_str_new_lit(mrb, "#"); + return ret; + } + members = struct_members(mrb, self); + mlen = RARRAY_LEN(members); + mems = RARRAY_PTR(members); + for (mrb_int i=0; i0) mrb_str_cat_lit(mrb, ret, ", "); + mrb_str_cat(mrb, ret, name, len); + mrb_str_cat_lit(mrb, ret, "="); + mrb_str_cat_str(mrb, ret, mrb_inspect(mrb, mrb_ary_ref(mrb, self, i))); + mrb_gc_arena_restore(mrb, ai); + } + mrb_str_cat_lit(mrb, ret, ">"); + + return ret; +} + /* * A Struct is a convenient way to bundle a number of * attributes together, using accessor methods, without having to write @@ -665,6 +708,8 @@ mrb_mruby_struct_gem_init(mrb_state* mrb) mrb_define_method(mrb, st, "initialize", mrb_struct_initialize, MRB_ARGS_ANY()); /* 15.2.18.4.8 */ mrb_define_method(mrb, st, "initialize_copy", mrb_struct_init_copy, MRB_ARGS_REQ(1)); /* 15.2.18.4.9 */ mrb_define_method(mrb, st, "eql?", mrb_struct_eql, MRB_ARGS_REQ(1)); /* 15.2.18.4.12(x) */ + mrb_define_method(mrb, st, "to_s", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.11(x) */ + mrb_define_method(mrb, st, "inspect", mrb_struct_to_s, MRB_ARGS_NONE()); /* 15.2.18.4.10(x) */ mrb_define_method(mrb, st, "size", mrb_struct_len, MRB_ARGS_NONE()); mrb_define_method(mrb, st, "length", mrb_struct_len, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-struct/test/struct.rb b/mrbgems/mruby-struct/test/struct.rb index db0fa56d8..384a92063 100644 --- a/mrbgems/mruby-struct/test/struct.rb +++ b/mrbgems/mruby-struct/test/struct.rb @@ -119,7 +119,7 @@ assert('struct inspect') do c = Struct.new(:m1, :m2, :m3, :m4, :m5, :recur) cc = c.new(1,2,3,4,5,nil) cc.recur = cc - assert_equal "#>", cc.inspect + assert_equal "#>", cc.inspect end assert('Struct#length, Struct#size') do