2012-11-08 63 views
7

在MRI中,看起來rb_id2str()負責在撥打Symbol#to_s時完成所有工作。我很驚訝地發現,對於我認爲是相當直接的操作,這是一個非常神祕的功能。MRI內部結構:rb_id2str的詳細解釋

我正在尋找這個功能在做什麼的詳細解釋。作爲參考,這裏是到源鏈接在1.9.3:

http://rxr.whitequark.org/mri/source/parse.y?v=1.9.3-p195#9950

一些具體問題:

什麼是四大if塊做什麼?

  1. if (id < tLAST_TOKEN)
  2. if (id < INT_MAX && rb_ispunct((int)id))
  3. if (st_lookup(global_symbols.id_str, id, &data))
  4. if (is_attrset_id(id))

這將是巨大的,得到的一般概述什麼內部的if語句的做法,但它不每個代碼塊」需要進行逐行分析。

最後,我很好奇的to_s內存/垃圾收集的意義:不調用Symbol#to_s創建具有進行垃圾回收每一次,或者是有類似的東西使用內部寫入時複製優化的新字符串直到對字符串進行突變爲止,對符號的實際表示的引用?

+0

'rb_id2str'做的不僅僅是這些。 '符號#to_s'實際上等同於'rb_sym_to_s'。該函數使用'SYM2ID'獲取對象的ID,然後只用'SYM2ID'返回的ID作爲參數來調用'rb_id2str',以從對象的ID構造字符串。不過,我可能會錯過一些步驟。我確信與'to_s'相關的內存使用情況,但我猜(並希望)它不會創建一個新的字符串 – omninonsense

回答

1

首先,我很確定Symbol#to_s創建一個新的字符串。 大部分ruby類都是C結構,除了TrueClass,FalseClass,NilClass,Fixnum和Symbol,它們都是C語言中的int。所以Symbol是一個完全不同的String(這就是爲什麼Symbol是推薦的,除非需要更改值)。

我不知道,如果你知道關於這本書紅寶石黑客指南,它解釋了很多關於MRI是如何用C實現

僅供參考,紅寶石黑客指南是用日語寫的,在此之前我還是有隻有一小部分被翻譯,看起來人們已經放棄了它。 http://rhg.rubyforge.org/