Posts Tagged ‘Symbol’

闲看RUBY内嵌对象(-): Symbol

我们在常听说符号类是ruby采用的一种轻量级的解决方案,可究竟如何轻量呢,为何在Rails中Symbol对象的身影随处可见呢; [...].map(&:name)、%w[mocha heckle].each(&method(:gem))背后又发生了哪些事情呢 ?
首先让我们来感受一下Ruby内部的符号表:

>> original_symbols_size = Symbol.all_symbols.size
=> 1776
>> class Test
>> attr_accessor :test
>> end
=> nil
>> updated_symbols_size = Symbol.all_symbols.size
=> 1779
>>
咦,多了俩
咱们来把那俩揪出来瞅瞅

>> class Test
>> attr_accessor :test
>> end
=> nil
>> Symbol.all_symbols – original_symbols
=> [:Test, :@test]
>>

可见Ruby把symbol存放在运行时维护的一个符号表里了,而这个符号表实际上是一个atom数据结构,其中存储着当前所有的程序级的identifier,确保不出现内容相同的多个对象。如果你再用一个已在符号表中“备案”的标识符去作类名,结果就是重新打开那个类,添加其定义体。

接着再让我们看看Symbol缘何能轻量,下面是它的C层次代码:
Symbol (ruby.h)
typedef unsigned long ID;
#define SYMBOL_FLAG 0×0e
#define SYMBOL_P(x) (((VALUE)(x)&0xff)==SYMBOL_FLAG)
#define ID2SYM(x) ((VALUE)(((long)(x))<<8|SYMBOL_FLAG))
#define SYM2ID(x) RSHIFT((unsigned long)x,8)

其中 VALUE 的typedef 是这样的
typedef unsigned long VALUE
到此我们即可看出Symbol对象就是存储为一个直接值嘛,果然轻量!
今天就切磋到这,最后再来一句意味深长,含义久远的::
Symbol对象代表代码解析树里的每个token。



收藏 & 分享

Powered by 17fav.com