4

私はこのコードを持っています:

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

スクリプトを実行すると、エラーがスローされます。

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

コードを次のように変更しました。

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

上記のコードは機能しますが、私はまったく好きではありません。gsubを適切に使用する方法はありますか?この場合?

4

2 に答える 2

7

いいえ。どうやら、文字列を提供するAPIが文字列をフリーズしているようです。つまり、文字列を変更するメソッドは失敗します。呼び出された文字列を変更するためgsub!、フリーズされたオブジェクトはを使用できませんgsub!。ただし、フリーズされたオブジェクトを含む変数は、フリーズされていないオブジェクトに設定できます。そのため、2番目のコードスニペットが機能します。

APIは、すべてのインスタンスが共有する定数文字列であるため、おそらくオブジェクトをフリーズします。したがって、1つのインスタンスが文字列を台無しにすることはできません。ただし、セッターメソッドを定義しているため、値を設定できます。

于 2012-08-29T17:50:34.227 に答える
5

@ pabloelices、

問題は、Stringによって参照されるオブジェクトsettings[:base_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\/\\:\*\?\"<>\|]/, ''

ただし、元のStringオブジェクトをgsub!呼び出すことはできません。

于 2012-08-29T17:55:38.673 に答える