《Ruby 元编程》读后总结

何时须要读这本书?

扫过一遍基本的 Ruby 语法,本身也写过一些 Ruby 代码,以为 Ruby 也就是一个普通的脚本语言而已的时候。编程

这本书带给读者什么东西?

在 Ruby 语法背后, Ruby 语言的构建模型。以及在这种模型下,一些可能只属于 Ruby 的实际编程案例(也就是怎么样用 Ruby 的特性去简化和优美你的代码)闭包

那么,元编程是什么?

通常来讲,『元xx』这样的词语都表示『创造 xx 的一种东西』或者『xx 背后更加原始的同样相似的东西』,好比 iOS 开发都很熟悉的 OC 中的元类。元编程表示的是『写出能够编写代码的代码』。函数

仍是抽象?举一个小例子:一个类中有二十个属性,如今你须要为这些属性分别创造对应的 set 方法,相似 setXXX 这样的形式,同时要求这些 set 方法都要判断新旧值是否一致,若是一致就直接 return。this

这样的事情显然是一个体力活,若是没有好的方法,你就须要写二十个十分相似的方法,而且每一个方法内部都差很少,只是在属性的名称那一部分有所区别,重复度很是高。spa

若是使用 Ruby 的元编程,当外部调用某个 set 方法(好比 setYYY)的时候,你的一段代码就会被执行,这段代码会动态的为当前的类建立一个 setYYY 方法,同时代码中能够截断方法名称(也就是拿到了一个 'YYY' 字符串),经过这个名称去动态获取对应属性的值(一种相似 this.get_property_by_name('YYY') 的方式),和当前 set 方法的参数进行比较,完成 set 方法的要求。整个代码可能不超过十行,而且不重复,十分优雅。3d

应该怎样阅读这本书?

首先咱们来看看这本书每一章的大体内容:对象

  1. 第一章:简单介绍了 Ruby 中面向对象的模型是怎么实现的,同时讲解了当调用一个对象的方法的时候发生了什么事情。blog

  2. 第二章:当咱们知道方法调用是怎样的一个流程之后,咱们就能够考虑是否能够拦截或者修改这个过程来实现一些黑魔法。ip

  3. 第三章:这里话头一转,转向描述 Ruby 中的代码块,也描述了和代码块息息相关的做用域的概念。作用域

  4. 第四章:这一章把话头又转回了类,这里将详细描述对象与类的组织模型,同时讲解了一些和类有关的元编程方法。

  5. 第五章:着重讲解 eval ,一个可以把字符串当作 Ruby 代码解释的函数。

  6. 第六章:休息一下,用一页纸讲个故事。

  7. 第七章-第八章:经过讲解 ActiveRecord 这个强大库的使用方法,将以前讲过的魔法汇总一下。

  8. 第九章:指出一些使用元编程的注意事项、经验教训。

  9. 附录:给出了一些 Ruby 中的常见事物的惯常写法,解释了什么是 DSL(领域专属语言),而后将前面讲到的魔法的例子汇总了一下。

能够看出,全书主要分两部分,第一部分主要是 Ruby 背后的模型的讲解、高级语法特性的讲解,中间穿插着一些例子。第二部分则是经过解析 ActiveRecord 这个库,将前面讲到的模型的利用来了个实际展现。

所以,最好第一遍阅读的时候着重去理解 Ruby 语言背后的模型,第二遍先看例子,本身尝试想一想要实现这些例子经过这些模型还须要什么东西,而后再看实际的例子。最后的附录能够在往后忘记一些写法的时候翻一翻,帮助回忆。

这本书中印象深入的点?

对象与类的模型和方法调用:

  1. Ruby 中的 class 关键字和 Java 等语言的 class 在理解上很不一样,Java 的 class 的做用是在全局建立一个类,而且这个类在全局只能有这一个声明;Ruby 中 class 做用是把代码的上下文变换到这个类中,也就是『打开类』,同一个类能够在任何地方被打开,也所以别人的类能够被本身随意打开并改写。

  2. Ruby 中的实例变量也不像 OC 或者 Java 那样必须提早声明,当第一次用到实例变量的时候,这个实例变量才会生成。因此在方法里头看到对一个实例变量赋值的时候有多是在初始化这个实例变量。

  3. 对象中不存储方法,只存储属性。对一个对象调用方法的时候,会首先去这个对象的 singlenton class 中找,而后去 singleton class 的父类中(实例对象的 singleton class 的父类是这个实例对象的类,类的 singleton class 的父类是这个类的父类的 singleton class ,类也是对象,不过特殊在类这个对象只有一个)。当调用方法的时候,首先去这个对象的 singleton class 中查找,没有的话继续向 singleton class 的父类查找,在以下完整的对象与类的结构图中能够简单记成『向右一步,而后向上』。enter image description here

  4. 定义类方法其实就是向类的 singleton class 中添加新的方法。

  5. 除了使用点语法调用方法,还可使用 send 方法来调用方法,这样就可使用字符串拼出来的方法名来调用方法了。(经过 send 甚至能够在外部调用类的私有方法)

  6. 可使用 define_method 来建立方法,和 def 的区别在于,define_method 后面能够是一个变量。

  7. method_missing 这个方法也能够动态增长方法。注意用这种方式的时候也要重写 respond_to? 方法。

  8. 模块有一个 included 的类方法,在这个模块被 include 的调用,咱们能够在里头写上自动增长类方法的代码,这样一个模块被 include 了之后,不止增长了实例方法,还增长了类方法,这个叫作类扩展混入(Class Extension Mixin)

  9. 一样一个 @a ,声明在类的做用域中和类的方法的做用域中是不同的。前者是类对象的实例变量,后者的类的实例对象的实例变量。

Block: 与 做用域

  1. 任何方法均可以传入一个 block ,不过有的方法会不处理 block ,此时传入 block 什么用也没有。

  2. 一个做用域能够理解为一个上下文环境,在同一个做用域中的代码能够互相访问彼此的变量。当有 class/def/module 的时候,代码会进入一个新的做用域,而且做用域之间并无什么关系,也就是说内部做用域不会获得外部做用域的变量(除了全局变量,全局变量是能够在任何做用域中获得的)。

  3. 可使用 block 利用闭包在不一样做用域之间传递变量。

  4. block 都是待着做用域的,也就是说 block 这个『行为』带着这个行为建立时的『数据』。

  5. 经过 method(:method_name) 能够获得一个 method 对象,不过 method 对象必须绑定到一个对象上才能被调用。

相关文章
相关标签/搜索