Ruby 冻结字符串-红宝石
我有以下代码:Ruby 冻结字符串-红宝石,ruby,string,Ruby,String,我有以下代码: settings[:base_name].gsub! /[\x00\/\\:\*\?\"<>\|]/, '' 我已将代码更改为: settings[:base_name] = settings[:base_name].gsub /[\x00\/\\:\*\?\"<>\|]/, '' settings[:base\u name]=settings[:base\u name].gsub/[\x00\/\\:\*\?\“\\\\”]/,“” 上面的代码
settings[:base_name].gsub! /[\x00\/\\:\*\?\"<>\|]/, ''
我已将代码更改为:
settings[:base_name] = settings[:base_name].gsub /[\x00\/\\:\*\?\"<>\|]/, ''
settings[:base\u name]=settings[:base\u name].gsub/[\x00\/\\:\*\?\“\\\\”]/,“”
上面的代码可以工作,但我一点也不喜欢,有没有办法正确使用gsub!在这种情况下?没有。显然,提供字符串的API已经冻结了它,这意味着任何修改它的方法都会失败。因为
gsub!
修改了它被调用的字符串,所以冻结的对象不能使用gsub!
。但是,variab包含冻结对象的le仍然可以设置为非冻结对象,这就是第二个代码段工作的原因
API可能冻结了该对象,因为它是所有实例共享的常量字符串,因此一个实例不应该破坏该字符串。但它们确实定义了一个setter方法,因此您可以设置该值。@pabloelices
问题在于设置[:base\u name]
引用的字符串
对象过去和现在实际上都是不可变的。您可以通过以下方式进行检查:
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\/\\:\*\?\"<>\|]/, ''
my_setting=settings[:base_name].dup#创建设置的副本。
设置[:base\u name]=my\u setting.gsub/[\x00\/\\:\*\?\“\\\\\”]/,“”
但是原始的
字符串
对象将不允许gsub要在其上调用的代码>。定义“正确”;冻结的字符串被冻结了。谢谢你的回复,很好的解释。@PabloElices:当然。很高兴我能帮忙。如果API的实现方式不同,您可以按照自己的方式来实现,但事实并非如此。你需要记住的是,虽然代码>方法修改调用它们的对象,它们不操纵变量。变量包含对象,对象被调用方法。区别是至关重要的。
my_setting = settings[:base_name].dup # Create a duplicate of the setting.
settings[:base_name] = my_setting.gsub /[\x00\/\\:\*\?\"<>\|]/, ''