Ruby看起来与众不同,基于一组精心设计的接口方法和作用域理论,形成了其优雅的语义模型。
但是万变不离其宗,了解了Ruby的对象模型,也就了解了其魔幻般的动态元编程原理。
[消息机制]
Ruby很好的继承和发扬了Smalltalk的面向对象理论。
在Ruby中,任何值是对象,原始类型如数字、字符串、布尔类型等是对象,甚至类和模块本身也是对象。
尽管对象的表示在形式上与一般数据类型十分相似,但是它们之间存在一种本质区别:对象之间通过消息传递方式进行交互。
对象交互的消息机制是面向对象更为本质的特征,为对象的交互提供了一种统一的形式,可以在运行时动态的创建消息,然后发送给合适的对象。
一般情况下,对象接收它能够识别的消息,拒绝它不能识别的消息。消息的名字就是这个对象公开的让外部可知的某个方法的名字。
由于类先于对象定义,对象是类的实例,所以一个类为它的实例提供了可以预知的对外交互方式。
让我们想象一下如果发送一条对象不能识别的消息会怎样?
这种情况在C++、Java、C#等静态类型语言中会得到一个方法未定义的编译错误,在JavaScript中则会产生运行时异常,但是在Ruby这样的动态语言中却别有一片天地。
[对象模型]
在Ruby中,对象就是一组实例变量加上指向其类的引用。
对象的方法不存在于对象本身,而是存在于对象的类中。
类本身也是一个对象(Class类的实例),因此类也有自己的实例变量和指向其类的引用。
同时,类有一组实例方法和一个对其超类的引用。
正如你所熟悉的C++/Java等语言,典型的情况是先定义类,并创建一个该类的对象,然后向该对象发送消息。
在Ruby中,每一行代码都会在一个对象中执行,这个对象就是当前对象,用self表示。
在一个给定时刻,只有一个对象是当前对象。当前对象随着语句的执行而动态的变化,没有哪个对象能长期作为当前对象。
在任何时刻都知道哪个对象在充当self是绝对重要的。
Ruby中的类定义也是执行代码,而类也是一个对象,因此在类定义中,self就是正在定义的类。
同样的,在程序执行的过程中,也一直存在当前类。
Ruby会追踪当前类或模块的引用,所有使用def定义的方法都成为当前类的实例方法。
在类定义中,当前类就是正在定义的类。如果有一个类的引用,可以使用class_eval()打开这个类。
另一方面,Ruby允许给单个对象增加方法,称为单件方法。
也许你会想,如果每个对象都有自己的方法,那这些对象的类型不就乱套了吗?
事实上,面向对象封装的无非是数据和行为,要判断一个对象属于什么类型只需要关注对象表现出来的行为即可。这种将对象类型认为是其能响应的一组方法的概念称为duck typing。
我们知道对象的方法不存在于对象自身,那么对象的单件方法又存在于哪里?
为了优雅的解决duck typing和对象类型之间的矛盾,Ruby引入了eigenclass。
一个对象的单件方法实际上是与它关联的eigenclass的实例方法。而类方法,实际上就是类的单件方法。
每个对象(包括类)都有自己的”真正的类“,可能是eigenclass,也可能是普通的类。
那么对象什么时候有eigenclass?
有2种情况,自动生成和显式生成。
在定义类的时候,Ruby会自动为你生成这个类的eigenclass,而其他的对象(包括模块)则需要显式生成。
普通的类与eigenclass之间又有什么关系?
一个对象的eigenclass的超类是这个对象的类,而一个类的eigenclass的超类是这个类的超类的eigenclass。
由于引入了eigenclass,Ruby的对象模型世界一下变得丰富多彩起来。
[方法调用]
说到方法调用,先来弄清楚方法修饰符public、protected与private。
Java中也有类似的方法修饰符,其中public作用一样,但是protected与private的区别很大:
Java中,任何方法都可以被同一个类型的其他对象调用;而Ruby中private方法不能被同一个类型的其他对象实例调用,因为不能明确指定一个接收者来调用私有方法。
Java中,private方法不能不继承;而Ruby中,不管protected还是private方法,都可以被子类继承。
为什么会有这样的行为差异呢?
Java强调继承关系,方法调用限定类继承的层次结构,但不限定同一类型的不同对象实例。
Ruby中一切皆对象,方法调用针对对象实例进行限定。不过虽然不能直接给私有方法指定接收者,也可以通过消息发送(send)来调用私有方法。
当调用一个方法时,也就是给一个对象发消息时,Ruby会怎样做?
首先,Ruby会把self设置为消息接收者,然后进入其”真正的类“进行方法查找,如果没找到则进入其祖先链一直往上查找。
如果找到了相应的方法,则以self为对象,调用该方法。如果一直到BasicObject都没找到这个方法,就会调用self的method_missing方法。
既然method_missing也是方法调用,那么又会进行新一轮的方法查找,所以覆盖method_missing方法就是元编程的一个重要手段。
经过方法查找,找到合适的方法后,就到了方法执行的阶段。
由于数据与方法是分开的,找到的方法只是可执行的代码而已。代码执行时需要一个执行环境,包括局部变量、实例变量、全局变量、常量、self等,也就是一组绑定。绑定存在于一个特定的作用域里面,而作用域会随着程序语句的执行进行动态切换。
Ruby有严格完整的作用域限制,程序会在三个地方进行作用域切换:类定义(class)、模块定义(module)、方法(def)。
可以使用Class.new()、Module.new()和define_method()分别代替class、module、def关键字,来避免作用域的切换。
搞清楚了对象、类、Eigenclass、作用域、消息、self、当前类等,也就搞清楚了Ruby的对象模型。
分享到:
相关推荐
1. Ruby对象模型:Ruby中的每个值都是一个对象,每个对象都有一个类,每个类都继承自Object类。Ruby的对象模型是理解元编程的基础。书中通过组织和解释Ruby对象模型的概念,帮助读者清晰理解Ruby的继承和混入机制。 ...
理解Ruby的对象模型是进行元编程的基础。通过了解对象是如何创建、如何存储数据以及如何交互的,我们可以更灵活地控制程序的行为。 2. **动态方法定义**:Ruby允许在运行时动态地添加新方法到类或对象上。这种能力...
Rails的ActiveRecord模型就是通过元编程来实现其魔法般的动态方法生成,例如,我们可以直接对模型使用find_by或where等方法,而这些方法在Ruby代码中是不存在的,它们是在运行时动态生成的。Rails的路由系统、视图...
- Carlo Pecchia表示,他从未找到过像这本书那样清晰地组织并解释Ruby对象模型、闭包、DSL定义等概念的作品。 - Chris Bunch认为,这是一本非常好的入门书籍,能够帮助开发者轻松地掌握Ruby中最复杂的秘密,并将其...
根据提供的文件信息,我们将深入探讨与“Ruby编程Ruby Programming”这一主题相关的几个核心知识点。这本面向初学者和高级读者的指南旨在全面介绍Ruby编程语言的基础及其高级特性,因此我们将从多个角度来解析这些...
1. **模型映射**:Her允许定义模型类,这些类与REST资源对应,提供了一种面向对象的方式来操作数据。例如,`class User 将User模型与API中的/users资源关联。 2. **关联关系**:Her支持关联模型,如一对一、一对多...
松本行弘在设计Ruby时融合了多种语言的优点,如**Perl**的实用性、**Smalltalk**的对象模型、**Eiffel**的语言结构、**Ada**的严谨性和**Lisp**的函数式编程特性。这种多元化的灵感来源赋予了Ruby独特的魅力,使其...
在Ruby中,`try` 方法是一个非常有用的功能,它允许我们安全地访问对象的方法或属性,即使该对象为 `nil` 也不会抛出异常。相反,如果没有找到对象或者对象为 `nil`,`try` 会返回 `nil`。 **示例代码:** ```ruby ...
1. **Ruby对象模型**:深入讲解Ruby对象模型的基本原理,包括类、模块、继承关系等,为理解元编程奠定基础。 2. **动态方法定义**:介绍如何在运行时动态地定义方法,这是Ruby元编程的一个重要方面。 3. **模块扩展...
Ruby编程语言,是一种面向对象的、动态类型的脚本语言,由日本人松本行弘于1995年设计并开发。它以其简洁、优雅的语法和强大的功能深受开发者喜爱,尤其在Web开发领域,Ruby on Rails框架的出现,极大地推动了Ruby的...
通过阅读这本书,你可以深入理解Ruby的面向对象模型、变量、控制结构、函数、模块和类的使用,学习如何编写清晰、优雅的Ruby代码。此外,书中还涵盖了元编程、异常处理、文件和I/O、正则表达式、网络编程、线程和...
Ruby是一种面向对象的、动态类型的编程语言,由日本的松本行弘(Yukihiro Matsumoto)于1995年设计并开发。它强调代码的简洁性和可读性,致力于提供一种更人性化、自然的编程体验。Ruby的语法结构清晰,易于理解和编写...
- **元编程**:Ruby 提供了一系列方法来实现元编程,例如 `eval`、`send`、`method_missing` 等。 - **多线程**:虽然 Ruby 本身不支持原生多线程,但它提供了线程(Thread)模型来模拟并发执行。 - **性能优化**:...
Ruby是一种高级、面向对象的脚本编程语言,由日本的松本行弘(Yukihiro Matsumoto)在1995年设计并创建。它以其简洁、优雅的语法和强大的编程模型而闻名,旨在提高程序员的生产力和代码可读性。本教程将带你深入学习...
Ruby on Rails(简称Rails)是一个用于开发Web应用程序的开源框架,基于MVC(模型-视图-控制器)架构模式。Rails通过约定优于配置的原则简化了Web应用的开发流程,使得开发者能够快速构建高性能的Web应用。Rails框架...
Ruby是一种简洁而功能强大的编程语言,由日本的松本行弘(Yukihiro "Matz" Matsumoto)在1993年开发,并于1995年公开发布。Ruby语言设计之初就非常注重开发人员的编程体验,它拥有自然、表达性强的语法,易于阅读和...
Ruby是一种面向对象的、动态类型的编程语言,以其简洁、优雅的语法和强大的元编程能力而受到开发者喜爱。在课程设计和编程作业中,学习Ruby开发这样的系统可以帮助学生深入理解面向对象编程的概念,以及如何利用这种...
* Ruby是一种面向对象语言,它支持封装、继承和多态等面向对象的特性。 * Ruby支持代码块和迭代器,使得编写简洁的代码变得更加容易。 * Ruby的语法非常灵活,可以使用多种编程风格编写代码。 * Ruby的核心库非常...