在MRI中,当您致电rb_id2str()
时,Symbol#to_s
似乎负责完成所有工作。我惊讶地发现这是一个非常神秘的功能,我认为这是一个相当直接的操作。
我正在寻找这个功能正在做什么的详细解释。作为参考,这里是1.9.3中源代码的链接:
http://rxr.whitequark.org/mri/source/parse.y?v=1.9.3-p195#9950
一些具体问题:
四大if
块有什么作用?
if (id < tLAST_TOKEN)
if (id < INT_MAX && rb_ispunct((int)id))
if (st_lookup(global_symbols.id_str, id, &data))
if (is_attrset_id(id))
如果能够对if语句中的每个代码块进行一般概述,那就太棒了,但它不需要是逐行分析。
最后,我对to_s
的内存/垃圾收集含义感到好奇:调用Symbol#to_s
是否创建了一个必须每次都进行垃圾收集的新字符串,或者是否有类似内部副本的内容-on-write优化,使用对符号的实现表示的引用,直到对字符串进行变异为止?
答案 0 :(得分:1)
首先,我非常确定Symbol#to_s创建了一个新字符串。 大多数ruby类都是C结构,除了TrueClass,FalseClass,NilClass,Fixnum和Symbol,它们都是C中的int。所以Symbol是一个完全不同的字符串(这就是推荐使用Symbol的原因,除非你需要多次更改值) 。
我不确定你是否了解Ruby Hacking Guide这本书,它解释了很多关于如何在C中实现MRI的方法。
仅供参考,Ruby Hacking Guide是用日语编写的,直到现在仍然只有一小部分被翻译,看起来人们已经放弃了。 http://rhg.rubyforge.org/