本文作者:冬瓜
校对:Edmond
CocoaPods 是使用 Ruby 这门脚本语言实现的工具。Ruby 有很多优质的特性被 CocoaPods 所利用,为了在后续的源码阅读中不会被这些用法阻塞,所以在这个系列中,会给出一些 CocoaPods 的番外篇,来介绍 Ruby 及其当中的一些语言思想。
今天这一篇我们来聊聊 Ruby 中的一些十分“动态”的特性:eval 特性和 alias 特性。
说说 Eval 特性
源自 Lisp 的 Evaluation
在一些语言中,eval
方法是将一个字符串当作表达式执行而返回一个结果的方法;在另外一些中,eval
它所传入的不一定是字符串,还有可能是抽象句法形式,Lisp 就是这种语言,并且 Lisp 也是首先提出使用 eval
方法的语言,并提出了 Evaluation 这个特性。这也使得 Lisp 这门语言可以实现脱离编译这套体系而动态执行的结果。
Lisp 中的 eval
方法预期是:将表达式作为参数传入到 eval
方法,并声明给定形式的返回值,运行时动态计算。
下面是一个 Lisp Evaluation 代码的例子( Scheme[1] 方言 RRS 及以后版本):
; 将 f1 设置为表达式 (+ 1 2 3)
(define f1 '(+ 1 2 3))
; 执行 f1 (+ 1 2 3) 这个表达式,并返回 6
(eval f1 user-initial-environment)
可能你会觉得:这只是一个简单的特性,为什么会称作黑魔法特性?
因为 Evaluation 这种可 eval 特性是很多思想、落地工具的基础。为什么这么说,下面来说几个很常见的场景。
REPL 的核心思想
如果你是 iOSer,你一定还会记得当年 Swift 刚刚诞生的时候,有一个主打的功能就是 REPL 交互式开发环境。
当然,作为动态性十分强大的 Lisp 和 Ruby 也有对应的 REPL 工具。例如 Ruby 的 irb 和 pry 都是十分强大的 REPL。为什么这里要提及 REPL 呢?因为在这个名字中,E 就是 eval 的意思。
REPL 对应的英文是 Read-Eval-Print Loop。
Read 读入一个来自于用户的表达式,将其放入内存;
Eval 求值函数,负责处理内部的数据结构并对上下文逻辑求值;
Print 输出方法,将结果呈现给用户,完成交互。
REPL 的模型让大家对于语言的学习和调试也有着增速作用,因为“Read - Eval - Print” 这种循环要比 “Code - Compile - Run - Debug” 这种循环更加敏捷。
在 Lisp 的思想中,为了实现一个 Lisp REPL ,只需要实现这三个函数和一个轮循的函数即可。当然这里我们忽略掉复杂的求值函数,因为它就是一个解释器。
有了这个思想,一个最简单的 REPL 就可以使