Ruby 我返回这里的方法是什么?

Ruby 我返回这里的方法是什么?,ruby,Ruby,我有一个问题,我已经找到了解决办法(或者这只是偶然的机会),但我希望有人能解释它为什么有效,以及Ruby在这里做什么 我正在用固定宽度的输出文本和ANSI颜色代码做一些事情。我不希望转义字符计入我的长度,因此我为String类编写了一个小方法来计算长度(不包括颜色代码): def length_minus_codes color_codes = [ "\033[30m", "\033[0m" , "\033[31m",

我有一个问题,我已经找到了解决办法(或者这只是偶然的机会),但我希望有人能解释它为什么有效,以及Ruby在这里做什么

我正在用固定宽度的输出文本和ANSI颜色代码做一些事情。我不希望转义字符计入我的长度,因此我为String类编写了一个小方法来计算长度(不包括颜色代码):

def length_minus_codes
 color_codes = [ "\033[30m",
                 "\033[0m" ,
                 "\033[31m",
                 "\033[32m",
                 "\033[33m",
                 "\033[34m",
                 "\033[35m",
                 "\033[36m",
                 "\033[37m",
                 "\033[40m",
                 "\033[41m",
                 "\033[42m",
                 "\033[43m",
                 "\033[44m",
                 "\033[45m",
                 "\033[46m",
                 "\033[47m",
                 "\033[1m",
                 "\033[22m",
                 "\033[7m",
                 "\033[27m"]

  #Create new variable to strip         
  stripped_self = self

  #loop through color code array
  for index in 0 ... color_codes.size

    #strip color codes from string
    stripped_self.gsub!(color_codes[index],"")
 end 

     #return variance of self to stripped self to
     #get length of string not including color codes
    return self.length - (self.length - stripped_self.length)
end
end
我认为它工作得很好,直到我意识到在它被调用后,它被调用的字符串中的字符代码被剥离

在决定改变这一点之前,我尝试了一些方法:

 stripped_self.gsub!(color_codes[index],"")
为此:

 stripped_self = stripped_self.gsub(color_codes[index],"")
现在它运行良好

我不明白的是为什么?我理解我在
gsub
上使用的就地方法(!)的基本概念,但它不是修改self,而是我在方法中设置的一个变量,其次,我只想返回字符串的长度,而不是实际的字符串

有人能解释一下这里发生了什么吗?

当你解释的时候

stripped_self = self
您只是创建一个对
self
string对象的新引用,而不是创建一个新字符串。因此,任何就地修改(在本例中通过
gsub!
)都将反映在
self
对象上

如果要创建非引用的新对象,则需要复制该对象:

stripped_self = self.dup

这里可能有一个更简单的解决方案,就是使用非bang版本的
gsub
,并将其保存到变量中<代码>gsub像bang方法通常所做的那样更改接收器,
gsub
只需安全地返回修改过的对象,而不会影响接收器。

好的,这是有意义的。因此,我可以使用do=self.dup,或者当我使用非就地版本的gsub时,它也会创建一个副本,因此不会影响self。谢谢值得注意的是,在不同的情况下,您可能希望使用
clone
而不是
dup
,但这超出了本问题的范围。