Ruby的对象模型,包含在下面这张图中:
首先要知道,Ruby中的类也是对象,类相比于其他对象特殊的地方在于能够产生对象,既然类是对象,那么它显然也有类,也就是所谓类的类,这个类的类在 Ruby中就是类的metaclass,图中的(OtherClass),(OtherClass)就是类OtherClass的klass(c层次), (OtherClass)存储了类的方法(类方法)和类的实例变量,并且是唯一的且不可实例化。在Ruby层次上我们想操作(otherclass)应该 类似:
ruby 代码
- class OtherClass
- end
- class << OtherClass <otherclass><otherclass></otherclass></otherclass>
- attr_accessor:name
- def test
- p 'hello'
- end
- end
- OtherClass.name='dennis'
- OtherClass.name => "dennis"
- OtherClass.test =>'hello'
图中的instance是OtherClass的一个实例,那么显然instance的class是OtherClass,可是图中的 (instance)又是什么呢?(instance)就是对象的singleton类,singleton类这个名称怪怪的,不过每个对象只能有一个 singleton类的角度上说也可以理解。看看下面的例子:
ruby 代码
- class OtherClass
- end
- instance=OtherClass.new
- class << instance <instance><instance></instance></instance>
- def test
- p "a.test"
- end
- attr_accessor:name
- end
- instance.test =>"a.test"
- instance.name="dennis"
- instance.name =>"dennis"
instance通过OtherClass.new创建,但是此时(instance)还不存在,这与(OtherClass)情况不同,每个类一经创建 就有一个metaclass,而对象就不一样,只有当你通过class << instance 语法(或者def instance.test等等)创建的时候,(instance)才被创建。注意test方法和name变量都将是instance对象特有的,类OtherClass并没有改变。 观察下,发现(instance)继承于OtherClass,引出类的metaclass与对象的singleton类的又一个区别:类的 metaclass继承自父类的metaclass,而对象的singleton类则是继承于对象的class。<instance>
那么当我们调用instance.class的时候,怎么不返回(instance)?这是c ruby在底层做了处理,instance的class在c ruby层次是(instance),当查找的时候忽略了singleton类以及下面将要谈到的include模块的代理类,沿着继承链上查找:
</instance>
cpp 代码
- 86 VALUE
- 87 rb_obj_class(obj)
- 88 VALUE obj;
- 89 {
- 90 return rb_class_real(CLASS_OF(obj));
- 91 }
-
- 76 VALUE
- 77 rb_class_real(cl)
- 78 VALUE cl;
- 79 {
- 80 while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) {
- 81 cl = RCLASS(cl)->super;
- 82 }
- 83 return cl;
- 84 }
-
- (object.c)
核心代码就是:
cpp 代码
- while (FL_TEST(cl, FL_SINGLETON) || TYPE(cl) == T_ICLASS) {
- cl = RCLASS(cl)->super;
- }
其中FL_TEST(cl,FL_SINGLETON)用于测试是否是singleton类,而TYPE(cl)==TL_ICLASS是否是包含模块的代理类,TL_ICLASS的I就是include的意思。
图中类OtherClass继承Object,这个是显而易见的,不再多说。而Object、Class和Module这三个类是没办法通过API创建 的,称为元类,他们的之间的关系如图所示,Object的class是Class,Module继承Object,而Class又继承Module,因此 Class.kind_of? Object返回true。Object的class是Class类,而Class类又是Object的子类,这个问题类似先有鸡,还是先有蛋的问题,是先有Object?还是先有Class?而c ruby的解决办法是不管谁先有,创建Object开始,接着创建Module和Class,然后分别创建它们的metaclass,从此整个Ruby的 对象模型开始运转。
cpp 代码
- 1243 rb_cObject = boot_defclass("Object", 0);
- 1244 rb_cModule = boot_defclass("Module", rb_cObject);
- 1245 rb_cClass = boot_defclass("Class", rb_cModule);
- 1246
- 1247 metaclass = rb_make_metaclass(rb_cObject, rb_cClass);
- 1248 metaclass = rb_make_metaclass(rb_cModule, metaclass);
- 1249 metaclass = rb_make_metaclass(rb_cClass, metaclass);
-
- (object.c)
那么当我们调用Class.class发生了什么?Class的klass其实指向的是(Class),可根据上面的代码,我们知道会忽略这个 (Class),继续往上找就是(Module),同理找到(Object),而(Object)继承自Class,显然Class的类仍然是 Class,Class的类的类也是Class,无穷递归下去,多么有趣。同理,Object.class和Module.class都将是Class类。
再来看看include模块时发生的故事。include模块的过程如下图所示:
include模块,本质上是在对象或者类的klass和super之间插入了一个代理类iclass,这个代理类的方法表(m_table)和变量表 (iv_table)分别指向了被包含的模块的方法表和变量表(通过指针,因此当包含的Module变化的时候,对象或者类也能相应变化),那么在查找类 或者对象的class的时候,上面已经指出将忽略这些代理类。
分享到:
- 2007-09-29 09:56
- 浏览 2805
- 评论(2)
- 论坛回复 / 浏览 (2 / 4677)
- 查看更多
相关推荐
第一部分的内容包括对Ruby语言一个概要介绍和对Ruby对象模型的讲解。从我个人阅读的感觉来看,第一章对于Ruby语言的介绍是一个非常好的起步教程,把Ruby语言中一些核心点都指了出来。比起我读到过一些Ruby语言教程,...
1. Ruby对象模型:Ruby中的每个值都是一个对象,每个对象都有一个类,每个类都继承自Object类。Ruby的对象模型是理解元编程的基础。书中通过组织和解释Ruby对象模型的概念,帮助读者清晰理解Ruby的继承和混入机制。 ...
1. **Ruby对象模型**:深入讲解Ruby对象模型的基本原理,包括类、模块、继承关系等,为理解元编程奠定基础。 2. **动态方法定义**:介绍如何在运行时动态地定义方法,这是Ruby元编程的一个重要方面。 3. **模块扩展...
**Ruby对象模型详解** Ruby是一种面向对象的编程语言,其对象模型是其核心特性之一,它使得Ruby在处理复杂的数据结构和程序设计时表现出强大的灵活性和简洁性。本讲解将深入探讨Ruby对象模型的各个方面,帮助你理解...
- Carlo Pecchia表示,他从未找到过像这本书那样清晰地组织并解释Ruby对象模型、闭包、DSL定义等概念的作品。 - Chris Bunch认为,这是一本非常好的入门书籍,能够帮助开发者轻松地掌握Ruby中最复杂的秘密,并将其...
- **Carlo Pecchia**:软件工程师,表示在阅读本书之前从未找到过关于Ruby对象模型、闭包、DSL定义和eigenclasses等概念的清晰组织和解释,本书充满了来自日常使用的gem的实际例子。 - **Chris Bunch**:软件工程师...
4. **自动序列化和反序列化**:Her可以自动将Ruby对象转换为JSON格式发送到服务器,同时也能将服务器返回的数据解析为Ruby对象。 5. **错误处理**:Her内置了错误处理机制,当API请求失败时,可以捕获并处理相应的...
ActiveRecord提供了一种简洁的方式将数据库操作与Ruby对象模型化,使得开发者可以方便地进行数据库查询和操作。然而,尽管ActiveRecord在许多场景下表现出色,但它并不总是最高效的解决方案,特别是在处理大规模数据...
Ruby的MongoMapper库就是为了让开发者能够更自然地在Ruby对象和MongoDB文档之间进行映射,从而简化数据操作。 MongoMapper的设计理念深受ActiveRecord的影响,它是Ruby on Rails框架中的核心组件,但MongoMapper...
Ruby FastJSONAPI 是一个专为Ruby对象设计的高性能JSON:API序列化库。它旨在帮助开发者以简洁、高效的方式将Ruby对象转换为符合JSON:API规范的JSON格式,极大地提高了开发效率和应用程序的性能。 JSON:API是一个...
### C#操作Excel(Excel对象模型)_v1.0 #### 概述 本文主要针对在Visual Studio中使用C#开发涉及Excel的应用程序。要利用C#语言进行Excel操作,理解Excel的对象模型至关重要。Excel的对象模型是Microsoft Office...
源码分析可以帮助开发者了解RubyXL如何解析XML结构,构建Ruby对象模型,以及如何处理数据和样式。通过查看源码,可以学习到XML解析技巧、Ruby面向对象编程以及如何编写高效的Ruby代码。 6. **扩展与自定义**: - ...
Form对象可以与任何数据结构进行绑定,包括ActiveRecord模型、 PORO(Plain Old Ruby Object)或者其他任何对象。这意味着Reform是数据库框架无关的,无论你使用的是ActiveRecord、DataMapper还是Sequel,都可以轻松...
### C#操作Word(word对象模型) #### 一、Word对象模型概述 Word对象模型是Microsoft Office Word 提供的一种编程接口,它使开发者能够通过编程的方式控制Word文档的各种功能,如文档创建、编辑、格式化等。对于...
Ruby 的常量查找路径问题是一直困扰我的一个问题,在工作中遇到过好几次,一直没有彻底弄清楚到底为什么,最近在读一本书《Ruby 元编程》,对 Ruby 对象模型有了更深入的认识,另外读了一篇 blog《Everything you ...
Ruby-SpreadsheetArchitect是一个强大的库,专门设计用于Ruby开发者,它允许将任何ActiveRecord关系或Ruby对象集合方便地导出为XLSX、ODS或CSV格式的电子表格文件。这个工具对于需要处理大量数据并希望以用户友好的...
Ruby on Rails是MVC(模型-视图-控制器)架构的忠实实践者,它提供了代码生成器、数据库迁移、ActiveRecord对象关系映射、ActionPack组件(包含ActionView和ActionController)等工具,大大提高了开发效率。...
1. **ActiveRecord**:这是Rails中负责数据库交互的部分,它将数据库记录映射为Ruby对象,提供了一种简单、直观的方式来操作数据。 2. **ActiveRecord ORM**:对象关系映射(ORM)使得开发者可以使用Ruby代码操作...
- **面向对象**:几乎所有事物在Ruby中都是对象,包括数字、字符串等基本数据类型。 - **动态性**:Ruby支持运行时修改代码结构,允许开发者在程序运行过程中改变类和方法的行为。 - **元编程能力**:Ruby提供了一种...
Ruby是一种面向对象的编程语言,以其简洁和表达性强的特点深受开发者喜爱。在Ruby的世界里,ActiveRecord是ORM(Object-Relational Mapping)的代表,它为数据库操作提供了强大的抽象层。然而,有时候我们并不需要完整...