我有一个问题,我已经找到了解决方案(或者可能只是机会),但我希望有人可以解释为什么它有效,并且<强大的>什么 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
上使用的就地方法(!)的基本概念,但它并没有修改自我,而是我在方法中设置的变量,其次我只想要返回字符串的长度,而不是实际的字符串。
有谁可以解释这里发生的事情?
答案 0 :(得分:2)
当你这样做时
stripped_self = self
您只是创建对self
字符串对象的新引用,而不是创建新字符串。因此,任何就地修改(在本例中为gsub!
)都将反映在self
对象上。
如果要创建不是引用的新对象,则需要复制该对象:
stripped_self = self.dup
答案 1 :(得分:0)
这里可能更简单的解决方案就是使用非爆炸版gsub
并将其保存到变量中。 gsub!
会像bang方法经常更改接收器,gsub
只会安全地返回修改后的对象,而不会影响接收器。