From 9709fe79a3a75eefc92329cc0b74e159ff31525f Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Thu, 5 Jun 2014 01:10:02 +0900 Subject: Implement String#clear --- src/string.c | 33 +++++++++++++++++++++++++++++++++ test/t/string.rb | 21 +++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/string.c b/src/string.c index 842e83d76..6fa9271e1 100644 --- a/src/string.c +++ b/src/string.c @@ -2523,6 +2523,38 @@ mrb_str_bytes(mrb_state *mrb, mrb_value str) return a; } +static inline void +str_discard(mrb_state *mrb, mrb_value str) { + struct RString *s = mrb_str_ptr(str); + + if (!STR_SHARED_P(s) && !STR_EMBED_P(s) && ((s->flags & MRB_STR_NOFREE) == 0)) { + mrb_free(mrb, s->as.heap.ptr); + RSTRING(str)->as.heap.ptr = 0; + RSTRING(str)->as.heap.len = 0; + } +} + +/* + * call-seq: + * string.clear -> string + * + * Makes string empty. + * + * a = "abcde" + * a.clear #=> "" + */ +static mrb_value +mrb_str_clear(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + + str_discard(mrb, str); + STR_SET_EMBED_FLAG(s); + STR_SET_EMBED_LEN(s, 0); + RSTRING_PTR(str)[0] = '\0'; + return str; +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -2574,4 +2606,5 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_REQ(1)); /* 15.2.10.5.43 */ mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); + mrb_define_method(mrb, s, "clear", mrb_str_clear, MRB_ARGS_NONE()); } diff --git a/test/t/string.rb b/test/t/string.rb index 5ecb51530..779a74791 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -515,3 +515,24 @@ assert('String#each_byte') do assert_equal bytes1, bytes2 end + +assert('String#clear') do + # embed string + s = "foo" + assert_equal("", s.clear) + assert_equal("", s) + + # not embed string and not shared string + s = "foo" * 100 + a = s + assert_equal("", s.clear) + assert_equal("", s) + assert_equal("", a) + + # shared string + s = "foo" * 100 + a = s[10, 90] # create shared string + assert_equal("", s.clear) # clear + assert_equal("", s) # s is cleared + assert_not_equal("", a) # a should not be affected +end -- cgit v1.2.3