diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index 572418313..70fb113b1 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -54,19 +54,6 @@ class String
# "abcd".insert(-3, 'X') #=> "abXcd"
# "abcd".insert(-1, 'X') #=> "abcdX"
#
- def insert(idx, str)
- if idx == -1
- return self << str
- elsif idx < 0
- idx += 1
- end
- self[idx, 0] = str
- self
- end
-
-
-
-
##
# Call the given block for each character of
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index da34a9a12..8c710e453 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -2106,6 +2106,54 @@ mrb_str_rpartition(mrb_state *mrb, mrb_value self)
return result_ary;
}
+/*
+ * call-seq:
+ * str.insert(index, other_str) -> str
+ *
+ * Inserts other_str before the character at the given
+ * index, modifying str. Negative indices count from the
+ * end of the string, and insert after the given character.
+ * The intent is insert aString so that it starts at the given
+ * index.
+ *
+ * "abcd".insert(0, 'X') #=> "Xabcd"
+ * "abcd".insert(3, 'X') #=> "abcXd"
+ * "abcd".insert(4, 'X') #=> "abcdX"
+ * "abcd".insert(-3, 'X') #=> "abXcd"
+ * "abcd".insert(-1, 'X') #=> "abcdX"
+ */
+static mrb_value
+mrb_str_insert(mrb_state *mrb, mrb_value self)
+{
+ mrb_int idx;
+ mrb_value str_to_insert;
+ mrb_get_args(mrb, "iS", &idx, &str_to_insert);
+
+ struct RString *s = mrb_str_ptr(self);
+ mrb_int self_len = RSTRING_LEN(self);
+ mrb_int insert_len = RSTRING_LEN(str_to_insert);
+ const char *insert_ptr = RSTRING_PTR(str_to_insert);
+
+ mrb_check_frozen(mrb, s);
+
+ if (idx < 0) {
+ idx = self_len + idx + 1;
+ }
+
+ if (idx < 0 || idx > self_len) {
+ mrb_raisef(mrb, E_INDEX_ERROR, "index %S out of string", mrb_int_value(mrb, idx));
+ }
+
+ mrb_str_modify(mrb, s);
+ mrb_str_resize(mrb, self, self_len + insert_len);
+
+ char *p = RSTRING_PTR(self);
+ memmove(p + idx + insert_len, p + idx, self_len - idx);
+ memcpy(p + idx, insert_ptr, insert_len);
+
+ return self;
+}
+
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
@@ -2122,6 +2170,7 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method_id(mrb, s, MRB_SYM(tr), str_tr_m, MRB_ARGS_REQ(2));
mrb_define_method_id(mrb, s, MRB_SYM(partition), mrb_str_partition, MRB_ARGS_REQ(1));
mrb_define_method_id(mrb, s, MRB_SYM(rpartition), mrb_str_rpartition, MRB_ARGS_REQ(1));
+ mrb_define_method_id(mrb, s, MRB_SYM(insert), mrb_str_insert, MRB_ARGS_REQ(2));
mrb_define_method_id(mrb, s, MRB_SYM_B(tr), str_tr_bang, MRB_ARGS_REQ(2));
mrb_define_method_id(mrb, s, MRB_SYM(tr_s), str_tr_s, MRB_ARGS_REQ(2));
mrb_define_method_id(mrb, s, MRB_SYM_B(tr_s), str_tr_s_bang, MRB_ARGS_REQ(2));