2013-09-27 102 views
0

紅寶石2.1將有一個凍結的繩子,讓對象不是重新創建每次解釋整個運行時間,即紅寶石2.1凍結串

my_hash["abcd"f] = 123 

爲什麼不能解釋自動檢測此字符串不會改變,只是自動凍結它?

或者,pre-ruby 2.1一旦解釋器開始運行,任何代碼如何更改這樣的字符串?如果我們說「abcd」需要被凍結,那麼就必須有某種方式來改變它。

- 更新:上面的問題進行了更新,所以在下面的評論是有點尷尬,但並非是針對以前的代碼示例的情況不是很好。

- UPDATE:http://globaldev.co.uk/2014/05/ruby-2-1-in-detail/ Ruby鍵會自動凍結。

+0

考慮'mydef.downcase!',它會修改返回的字符串。現在,如果你想在2.1之前的凍結/ interned字符串,你只需使用符號。 –

回答

1

Ruby是一種動態語言。沒有靜態編譯,解釋器很難預先知道誰最終會訪問和修改變量。

我們來看下面的例子。你有一個string

str = "foo" 

,然後後面的代碼中你有

str.upcase! 
# => "FOO" 

這個例子是非常微不足道的,即使是簡單的解析器,瞭解該字符串突變。但是,讓我們添加一些更復雜

str = "foo" 
method = ["up", "case"] 
str.send((method << "!").join) 
# => "FOO" 

這正是生產之前相同的結果,但該方法不是靜態腳本編碼。相反,它是在運行時在字符串上動態執行的計算的結果。

但是等等,讓我們把它變得更加複雜。

str = "foo" 
method = [ARGV.first, "case"] 
str.send((method << "!").join) if ARGC.to_i > 0 
# => "FOO" 

在這種情況下,假設我從命令行傳遞參數,轉換方法將被計算並應用於字符串。

正如你所猜測的,在這兩種情況下知道str將要改變的唯一方法是通過實際執行代碼。

這些例子也應該回答你的問題

How could any code change such a string once the interpreter has started running? If we say that "abcd" needs to be frozen, then there must be some way of changing it.

補充說明的第二部分,我想指出的是,「凍結字符串文字」功能,最近已演變,它現在足夠將變量標記爲frozen

In Ruby 2.1, "str".freeze is optimized by the compiler to return a single shared frozen strings on every invocation. An alternative "str"f syntax was implemented initially, but later reverted.

2
  • 關於你提到的第一個問題:

    因爲解釋不能預見是否該字符串實例會被任何破壞性的方法,在以後修改。

  • 關於你提到的第二個問題( 「或」 後):

    通過任何對String破壞性的方法,如reverse!prependconcat

+0

如果字符串被自動凍結,'mydef.sub!('a','o')'會拋出不需要的RuntimeError。這是你的觀點的一個例子嗎? (這取代了之前措辭不佳的評論。) –

+0

我試過mydef.sub!('a','!')。下一次通話時,mydef仍會返回'abcd'。 – Daniel

+0

我清理了措辭@CarySwoveland – Daniel