2014-07-18 66 views
4

我不清楚符號的值和正確使用。何時使用Ruby中的符號

好處似乎是通過讓它只存在於內存中來消除對同一個散列的多個副本的需要。我想知道這是否屬實,還有其他什麼好處。

如果我創建的屬性如name,emailpassword以及每個屬性使用的符號而不是字符串,是否意味着每個屬性只有一個對象?看起來這樣可以避免散列中的屬性的字符串副本(這看起來像是一件好事)。

有人能幫我理解一個符號是什麼以及什麼時候在散列中使用一個字符串更好?每個的好處和缺陷是什麼?

另外,任何人都可以談論每個內存的權衡?由於可擴展性很重要,我很好奇符號是否有助於提高速度。

+2

http://stackoverflow.com/questions/2341837/understanding-symbols-in-ruby可能是有用的 – JKillian

+0

真棒,謝謝。你知道相關的記憶折衷嗎?我可以看出,創建的對象較少,我認爲一般情況會更好。但我對實際的表現體驗感到好奇,也對實際的權衡有更多的瞭解。 – markthethomas

+0

我不明白你爲什麼提到哈希。散列與你的問題有什麼關係?我不知道你的意思是「需要同一個散列的多個副本」。 – sawa

回答

4

符號,或「內部」因爲他們也被稱爲是有用的哈希鍵,常見的參數,和其他地方具有許多具有相同值的重複字符串的開銷是低效的。

例如:

params[:name] 
my_function(with: { arguments: [ ... ] }) 
record.state = :completed 

這些是通常優選爲字符串,因爲它們將被重複頻繁

最常見的用途是:

  • 哈希鍵
  • 方法的參數
  • 選項標誌或枚舉類型的屬性值

這是更好地處理用戶數據時使用的字符串的未知組成。不像可以垃圾收集的字符串,符號是永久的。將任意用戶數據轉換爲符號可能會使用垃圾填充符號表,並且如果某人有惡意,可能會導致應用程序崩潰。

例如:

user_data = JSON.load(...).symbolize_keys 

這將允許攻擊者以,假以時日,將與各種無用的垃圾的臃腫的過程中故意長的,隨機的名字創建JSON數據。

+0

安全觀點很好,絕對是我會記住的。爲了澄清:我實際上從來不想使用符號來引用可能會改變的一段數據,對嗎? – markthethomas

+0

符號幾乎不用於存儲「數據」,雖然它們可能會用作[enum](http://en.wikipedia.org/wiki/Enumerated_type)。沒有理由的符號化字符串數據通常會適得其反。 – tadman

+0

Gotcha;所以實際的使用可能是沿着像爲每個用戶分配一個對象的內部引用這樣的東西?這似乎是(隱約)到目前爲止我所見過的唯一實際用例。你能幫助我更好地理解嗎? – markthethomas

0

你應該考慮像數字這樣的符號。它是恆定的,不可改變的,那是在第一次使用創建的非GC對象,每當你需要引用到對象不能被複制,像你應該使用它們:

  • 消息又名方法(Ruby沒有超載)
  • 哈希鍵(Ruby並不多哈希)
0

是的,你的例子很好。

名稱,電子郵件和密碼都可以作爲符號存儲,即使在散列中 - 特定對象仍可以是字符串對象。

{ 
    :name => 'John doe', 
    :email => '[email protected]', 
    :password => 'lassdgjkl23853' 
} 
+0

謝謝! :)我猜想我得到的更多是符號的合適用例,而不是它們是否可以存儲在哈希中。也許我的問題並不像我想要的那樣清楚 – markthethomas

1

除了避免重複的存儲器分配的需要,可以將符號的相等不是字符串更快進行比較,並且它們的散列碼可被計算比串更快(所以無論存儲和從Hash檢索數據會更快時符號而不是字符串鍵被使用)。

在內部,Ruby使用與符號緊密相關的東西來標識方法,類的名稱等等。因此,例如,當您檢索一個對象支持的方法列表(使用obj.methods)時,您將得到一組符號。當你想要「動態地」調用一個方法時,使用一個存儲在變量中的名字或者作爲參數傳入的方法,你必須使用一個符號。同樣也用於獲取/設置實例變量,常量等的值。

直覺上,你可以這樣想。如果你用C編程過,你寫的東西,如:

#define SOMETHING 1 
#define SOMETHING_ELSE 2 

這些define小號不再需要在代碼中使用「幻數」。使用的名稱(SOMETHING等)與您的程序用戶無關,就像函數或類的名稱與用戶無關。它們只是代碼內部的「標籤」,只是程序員所關心的。符號在Ruby程序中扮演着相似的角色。它們是一種數據類型,它的性能屬性類似於整數,但是它們的字面語法使得它們對人類程序員來說顯示爲有意義的名稱。

一旦你「獲得」了Ruby符號的概念,理解Lisp符號將會容易得多,如果你曾經在Lisp中編程的話。在Lisp中,符號是程序代碼組成的基本數據類型。 (因爲Lisp程序是數據,可以這樣操縱。)