美文网首页程序员
Ruby 的魔法世界——元编程(一)

Ruby 的魔法世界——元编程(一)

作者: Sheepy | 来源:发表于2016-03-03 15:25 被阅读655次

什么是元编程(Metaprogramming)

元编程就是编写能写代码的代码。

能写代码的代码……是指代码生成器么?Java注解?C++模板?这些在广义上也属于元编程。不过这些过程发生在编译期(compiler time),称为静态元编程;本文准备介绍的 Ruby 元编程,是编写能在运行时(runtime)操作自身的代码,称为动态元编程。

这样一来你会发现 OC 中的 Swizzle 啊关联对象啊等运行时黑魔法都可以算作元编程的范畴。所以元编程其实无处不在,几乎可以说元编程就是动态语言的设计模式,等到掌握了元编程的技巧之后,你会发现:

根本没有什么元编程,从来只有编程而已。

这波我给满分.jpg

对象模型

要介绍 Ruby 元编程,首先要介绍一下 Ruby 的对象模型。

Ruby 号称是一门“纯”面向对象的语言,那到底有多纯呢,先看个图:

Ruby 对象模型.png

上图中的箭头表示从属关系,譬如 obj1 指向 MyClass 的那个箭头表示“obj1 的 class 是 MyClass”。也就是说,obj1、obj2、obj3 是 MyClass 类的三个实例,也就是我们常说的对象,而 MyClass 其实是 Class 的一个实例,所以它也是一个对象。

其实,在 Ruby 中:

  • 一个对象的实例变量存在于对象本身之中,而一个对象的方法存在于对象的类中。
  • 对象就是一组实例变量外加一个指向其类的引用。
  • 类就是一个对象(Class 类的一个实例)外加一组实例方法和一个对其超类的引用。
  • Class 类是 Module 类的子类,因此一个类也是一个模块。

打开类

既然类也是一个对象,所谓的类名其实就只是一个常量。class关键字在某种程度上更像是一个作用域操作符,而不是类型声明符,class关键字把你带到类的上下文中,你可以在里面执行任何语句:

3.times do
  class C
    puts "Hello"
  end
end

< Hello
  Hello
  Hello

上面这段代码是不是定义了三个同名的类呢?不是的,第一次的时候会定义一个 C 类,之后就只是重新打开这个已经存在的类。

重新打开一个已经存在的类并对它进行动态修改,这种技巧叫打开类(open class)。我们可以给任何类添加新的方法,或者修改已存在的方法。当然这有一定的风险,你可能想添加一个新方法,却无意中覆写了原先已经存在的方法。所以也有人把这种技巧称为猴子补丁(Monkeypatch)。

待续。

参考:《Ruby 元编程》

相关文章

  • Ruby 的魔法世界——元编程(一)

    什么是元编程(Metaprogramming) 元编程就是编写能写代码的代码。 能写代码的代码……是指代码生成器么...

  • Ruby元编程笔记 - 类中的魔法

    Ruby元编程笔记 - 类定义 类定义揭秘 在类定义中,self就是正在定义的类。 所有使用def定义的方法都成了...

  • Ruby元编程

    类 方法 代码块 类宏 Eval方法 实例变量、方法、类 实例变量(Instance Variables)是当你使...

  • ruby元编程

    对象模型 所有class定义之外的代码默认运行在顶级对象main中。 打开类 ruby的class更像是一个作用于...

  • 我眼中的元编程-对象模型篇

    作为一个Ruby开发者,让人又爱又恨的便是元编程了。 【前言】元编程是什么 简单地说,元编程就是对语言本身的进行操...

  • 2016-11-04 task-list

    今日任务 ruby on rails 第四章 ruby 元编程 今日总结 ruby 单引号与双引号字符串的重大区别...

  • ruby元编程(1)

    面试中碰到一些面试官提到的关于ruby元编程的问题的总结 class和module的区别 官方说明class do...

  • Ruby元编程示例

  • ruby元编程(附录)

    拟态方法 拟态方法就是去掉括号调用方法的方式,会给ruby开发者带来很多语法糖,当然也会给开发者和ruby本身增加...

  • Ruby元编程(蛋人)

    01 Ruby元编程介绍和使用场景02 Ruby的类结构03 Singleton Method单例方法以及supe...

网友评论

    本文标题:Ruby 的魔法世界——元编程(一)

    本文链接:https://www.haomeiwen.com/subject/mqdnkttx.html