Ruby 获取can';使用string.insert时,请不要修改冻结的字符串

Ruby 获取can';使用string.insert时,请不要修改冻结的字符串,ruby,Ruby,这是一个简单的问题。我有下面的ruby代码,运行良好 def add_zeros number, zeros number = number.to_s zeros_to_add = zeros - number.length zeros_to_add.times do number = "0#{number}" end number end 但如果我替换 number = "0#{number}" 与 然后我得到了TypeError

这是一个简单的问题。我有下面的ruby代码,运行良好

  def add_zeros number, zeros
    number = number.to_s
    zeros_to_add = zeros - number.length
    zeros_to_add.times do
      number = "0#{number}"
    end
    number
  end
但如果我替换

number = "0#{number}"


然后我得到了TypeError:无法修改冻结字符串,有人知道这是为什么吗

如果传递的参数
number
已经是一个冻结的字符串,则
number=number.to\u s
不会更改任何内容,并且您将无法在适当的位置修改它(使用
number.insert
):

当然,从中创建新字符串(
“0{number}”
)不是问题

您的字符串冻结的原因很微妙。当您使用字符串作为散列键时,Ruby将复制并冻结该字符串:

s = "hello"
h = {}
h[s] = :world
key = h.keys.first  
key.equal?(s)  # => false  (Ruby made a copy)
key.frozen?    # => true   (Ruby automatically freezes the copy)
无论如何,作为一般规则,一个方法不应该修改它的参数

在这种情况下,您可能需要使用
rjust

24.to_s.rjust(10, "0") # => "0000000024"

如果传递的参数
number
已经是一个冻结的字符串,则
number=number.to\s
不会更改任何内容,并且您将无法在适当的位置修改它(使用
number.insert
):

当然,从中创建新字符串(
“0{number}”
)不是问题

您的字符串冻结的原因很微妙。当您使用字符串作为散列键时,Ruby将复制并冻结该字符串:

s = "hello"
h = {}
h[s] = :world
key = h.keys.first  
key.equal?(s)  # => false  (Ruby made a copy)
key.frozen?    # => true   (Ruby automatically freezes the copy)
无论如何,作为一般规则,一个方法不应该修改它的参数

在这种情况下,您可能需要使用
rjust

24.to_s.rjust(10, "0") # => "0000000024"

你使用的是什么版本的Ruby?我无法在OSX上的1.8.6、1.8.7或1.9.2中重现该错误。这对我来说很好。另一种方法是:是否有任何其他代码可能会影响编号的状态?感谢您的回复,我在mac os上使用ruby 1.8.7,当我在测试def test_Zero{“43544”=>“43544”,“344”=>“00344”,5=>“00005”,100=>“00100”)时会发生此错误。每对都有输入,expected | string=@bs.add_zero(input,5)assert_equal(string.class,string)assert_equal(string,expected,“应该是#{expected}但是#{string}”)end是我让它在带有@bs实例cheers richard的类中运行的吗?您使用的是什么版本的Ruby?我无法在OSX上的1.8.6、1.8.7或1.9.2中重现该错误。这对我来说很好。另一种方法是:是否有任何其他代码可能会影响编号的状态?感谢您的回复,我在mac os上使用ruby 1.8.7,当我在测试def test_Zero{“43544”=>“43544”,“344”=>“00344”,5=>“00005”,100=>“00100”)时会发生此错误。每对都有输入,expected | string=@bs.add_zero(input,5)assert_equal(string.class,string)assert_equal(string,expected,“应该是#{expected}但#{string}”)end是#{string}end,我让它在一个带有@bs实例cheers richards的类中运行感谢您的回答,我不知道我传递的字符串是一个冻结的字符串(但现在我想起来了,作为参数传递的字符串是否会自动被视为
冻结
??)。我想我可能需要更多地了解这一点!!我想在传递整数的情况下添加number.to_,尽管有时可能是字符串。但我会看更多关于冻结字符串的信息,非常感谢您的建议,非常感谢。还感谢关于rjust的提示,这非常有帮助,我将改用它!啊,对了,我忘了说为什么你的绳子一开始就冻住了。检查我的更新答案。感谢您的回答,我不知道我传递的字符串是冻结字符串(但现在我想起来了,作为参数传递的字符串是否自动被视为
冻结
??)。我想我可能需要更多地了解这一点!!我想在传递整数的情况下添加number.to_,尽管有时可能是字符串。但我会看更多关于冻结字符串的信息,非常感谢您的建议,非常感谢。还感谢关于rjust的提示,这非常有帮助,我将改用它!啊,对了,我忘了说为什么你的绳子一开始就冻住了。检查我的最新答案。