查看Ruby Under a Microscope的源代码
←
Ruby Under a Microscope
跳转到:
导航
、
搜索
因为以下原因,你没有权限编辑本页:
您刚才请求的操作只有这个用户组中的用户才能使用:
用户
您可以查看并复制此页面的源代码:
== 对象与类 == === Ruby 对象 RObject === * 在 include/ruby/ruby.h 中定义: <pre> struct RBasic { VALUE flags; const VALUE klass; } #ifdef __GNUC__ __attribute__((aligned(sizeof(VALUE)))) #endif ; struct RObject { struct RBasic basic; union { struct { uint32_t numiv; VALUE *ivptr; void *iv_index_tbl; /* shortcut for RCLASS_IV_INDEX_TBL(rb_obj_class(obj)) */ } heap; VALUE ary[ROBJECT_EMBED_LEN_MAX]; } as; }; </pre> 其中: RBasic 里的 class 指针指向了 RClass,也就是对象所属的 class。 flags 用于存储内部专用的各种标志位。 numiv 表示实例变量数目 ivptr 实例变量数组 iv_index_tbl 指向散列表的指针,该散列表保存了实例变量名(ID) 及其在 ivptr 数组中位置的映射,这些散列值存储在 RClass 的结构体中,该指针只是一个简单的缓存来加速访问。 * 基本类型对象,比如字符串、数组、正则表达式等有单独的结构体,例如 RString 、RArray 和 RRegexp 等等,每个实例内部同样有 basic 指针。 <pre> struct RString { struct RBasic basic; union { struct { long len; char *ptr; union { long capa; VALUE shared; } aux; } heap; char ary[RSTRING_EMBED_LEN_MAX + 1]; } as; }; struct RArray { struct RBasic basic; union { struct { long len; union { long capa; VALUE shared; } aux; const VALUE *ptr; } heap; const VALUE ary[RARRAY_EMBED_LEN_MAX]; } as; }; </pre> 等等。但是数字、符号等一些简单的立即值,没有使用任何结构体,而是直接将它们放到 VALUE 内,并且留前面几个 bit 位来标记类型: <pre> [ Integer value | Flags ] </pre> 基本类型对象也有实例变量,但是单独保存在 generic_iv_tbl 的特殊散列表里。 === RClass 结构体 === * Ruby 2.3.0 开始将 RClass 从 include/ruby/ruby.h 迁移到了 internal.h 中,为了信息隐藏: <pre> struct rb_classext_struct { struct st_table *iv_index_tbl; struct st_table *iv_tbl; struct rb_id_table *const_tbl; struct rb_id_table *callable_m_tbl; rb_subclass_entry_t *subclasses; rb_subclass_entry_t **parent_subclasses; /** * In the case that this is an `ICLASS`, `module_subclasses` points to the link * in the module's `subclasses` list that indicates that the klass has been * included. Hopefully that makes sense. */ rb_subclass_entry_t **module_subclasses; rb_serial_t class_serial; const VALUE origin_; VALUE refined_class; rb_alloc_func_t allocator; }; struct RClass { struct RBasic basic; VALUE super; rb_classext_t *ptr; struct rb_id_table *m_tbl; }; </pre> 其中: m_table 是方法的散列表,以方法名或者 ID 为键,以每个方法的定义的指针为值。 iv_index_tbl 是属性名散列表,是实例变量名和 RObject 实例变量数组属性值索引位置的映射。RObject 里有 iv_index_tbl 缓存指向这个散列表。 iv_tbl 类级别的实例变量和类变量,包括他们的名字和值。 const_tbl 常量散列表。 origin 用于实现 Module#prepend 特性。 allocator 用于分配内存。 super 指向超类 RClass 的指针。 * 类变量(@@)和类的实例变量(@)的区别:类变量在所有子类中共用;类实例变量在该类和子类中创建各自独自的值。但是他们都保存在 iv_tbl,通过名字区分。 * 类变量的查找顺序是会从该类和超类找起来,找到最高层的的超类的变量副本。而类的实例变量只在当前类查找。 * 类的类方法 (self.xxx) 是保存在元类 metaclass, 类的 RBasic 里 klass 指向的就是它的元类。一个小实验: <pre> irb(main):001:0> ObjectSpace.count_objects[:T_CLASS] => 912 irb(main):002:0> class Test end => nil irb(main):003:0> ObjectSpace.count_objects[:T_CLASS] => 914 </pre>
返回到
Ruby Under a Microscope
。
个人工具
登录
名字空间
页面
讨论
变换
查看
阅读
查看源代码
查看历史
操作
搜索
导航
首页
社区专页
新闻动态
最近更改
随机页面
帮助
工具箱
链入页面
相关更改
特殊页面