冻结的字符串 - Ruby

时间:2012-08-29 17:38:28

标签: ruby string

我有这段代码:

 settings[:base_name].gsub! /[\x00\/\\:\*\?\"<>\|]/, ''

当我运行脚本时,它会抛出一个错误:

gsub!': can't modify frozen String (RuntimeError)

我已将代码更改为:

 settings[:base_name] = settings[:base_name].gsub /[\x00\/\\:\*\?\"<>\|]/, ''

上面的代码有效,但我完全不喜欢,有没有办法正确使用gsub!在这种情况下?

2 个答案:

答案 0 :(得分:7)

没有。显然,提供字符串的API已将其冻结,这意味着修改它的任何方法都将失败。由于gsub!修改了调用它的字符串,因此冻结对象无法使用gsub!。但是,包含冻结对象的变量仍然可以设置为非冻结对象,这就是您的第二个代码段工作的原因。

API可能会冻结对象,因为它是所有实例共享的常量字符串,因此一个实例不应该破坏该字符串。但它们确实定义了一个setter方法,因此您可以设置该值。

答案 1 :(得分:4)

@pabloelices,

问题是String引用的settings[:base_name]对象已经frozen,现在实际上是不可变的。您可以通过以下方式查看:

settings[:base_name].frozen?  # => will return 'true'

您可以通过执行以下操作来清理代码和意图:

my_setting = settings[:base_name].dup   # Create a duplicate of the setting.
settings[:base_name]  = my_setting.gsub /[\x00\/\\:\*\?\"<>\|]/, ''

但原始的String对象不允许在其上调用gsub!