是gsub!复制字符串的缓冲区?

时间:2013-10-12 23:16:16

标签: ruby

在这两种情况下,我想知道在#gsub调用期间字符串对象的内部字符串缓冲区是如何更新的:

  1. 未进行替换。例如"hello".gsub!('r', 'a')
  2. 搜索字符串和替换字符串的字节长度完全相同。例如,"hello".gsub!('e', 'a')
  3. 在这两种情况下,将#gsub创建一个新的字符串缓冲区,将原始缓冲区复制到新的缓冲区,然后扔掉原来的?或者替换是否就地完成?

1 个答案:

答案 0 :(得分:3)

根据最后一个参数,MRI只有一种方法str_gsub可以同时处理gsubgsub!

static VALUE str_gsub(int argc, VALUE *argv, VALUE str, int bang)

如果找不到匹配项,则方法只返回nilgsub!)或字符串副本(gsub):

beg = rb_reg_search(pat, str, 0, 0);
if (beg < 0) {
if (bang) return Qnil;  /* no match, no substitution */
return rb_str_dup(str);
}

否则,将创建一个新的字符串缓冲区:

dest = rb_str_buf_new(blen);

然后执行替换,然后替换字符串(gsub!)或返回新实例(gsub):

if (bang) {
    rb_str_shared_replace(str, dest);
}
else {
RBASIC(dest)->klass = rb_obj_class(str);
OBJ_INFECT(dest, str);
str = dest;
}
if (tainted) OBJ_TAINT(str);
return str;