Roda 源码分析系列目录
前言
大家好,我是MARK24 。可以叫我 MARK。这是我研究Roda,做的记录。水平有限,欢迎指正。
研究的Roda源码版本 2022年2月9日 Roda v3.52.0 dc600b763ebf4f15e11c0428e26b812b9d140911
阅读本文章,你可能获得
- Rack 应用概念的了解
- Roda 树形路由的原理
- Ruby Class中 extend、include 的技巧
- Ruby 中 catch、throw 的使用
- 阅读源码的方法
以及欣赏 Roda 的设计等。
我个人水平和精力有限,研究Ruby时间不长,自认还是个小学生。如有错误欢迎指正,欢迎交流~
一、预备知识:Rack工作原理
熟悉的可以跳过 Rack 部分。
Roda本质上还是有一个 Rack 的应用。用户请求发送至我们的服务器,首先经过 Rack,所以先要明白 Rack的工作原理。
这篇文章简单的介绍了 Rack的工作流程
想要深入了解 Rack 可以查看官网源码
有一部国人编写的笔记也可以提供很大的帮助,可以下载:【RackProgram.pdf
】 (走我的博客吧,不方便再搞一遍了:Roda源码分析(二)请求响应 )
二、研究方法总结
Roda只是一个研究对象,研究方法是通用的。
1.把握宏观,要分清楚几个大类,每个方法在哪个大类下工作,决定了理解他们的角色
大概只需要关注,大类、和 initialize 方法。这里决定了他们初始化的值。
可以理解未来都是围绕着 initialize 里面的数据。
2.从入口开始往上找调用方法看看调用关系
阅读代码不应该从代码层面的 从上往下读。这是错误的。
根据语言的运行特点,以Ruby为例。应该以 解释器或者编译的运行顺序来观察源码。
1)代码初始化,进行了什么
class类声明、以及类中可执行语句在运行。可以关注下 class 中 initialize 中声明的变量,以及动态生成的代码。(Ruby和其他语言不一样,class内部也有代码在运行,你应该知道的。)
- 入口开始,调用关系
建立完内存中初始化的 class 等对象。就可以站在程序运行的角度,从入口调用的顺序 依次查看源码。
3.分析工具
主要使用他们的一些功能帮助阅读。有人可能觉得 DEBUG 工具就够了,我的体会不是这样,DBEUG 的切入点太细碎,而且不够准(我总是这个感觉)。跳转的地方往往涉及面太广,出错了要再次重来。当然可能我不会用啦。不过这些不重要。
真正重要的部分其实是明白Ruby工作的机制,以及按照Ruby运行的规律,去解读源码的主要部分,识别作者的意图。我觉得这个才比较重要。
1)VScode 编辑器
- 全局搜索变量、函数定义
- 查看单个代码文件的 大纲(Outline)即 类、方法 定义一览
2)RubyMine(或者一款IDE)
- DEBUG 功能,可以查看过程(不过这不是万能的,因为 DEBUG 对窥探全局并不好用。实际结果还是要以阅读为主)
- 跳转定义或者使用
- 修改我们使用的 lib库 即 Roda 源码,验证自己的猜想(动态语言的优势,一切都是透明的。使用完可以重新安装)
- 草稿纸
记录重要的引用关系,记录分析和思考。
三、Roda中使用的Ruby的知识
1.class的上下文中,attr语句会执行、@语句会执行、def语句会注册但是不会执行(实例化被实例调用执行),class上下文的 define_method 会执行
2.def 首次运行只注册不允许,具体的 def 的方法调用顺序,根据 启动app的顺序依次调用
3.Ruby的对象模型,以及 extend、include
这部分主要看插件系统好了。作者在 Ruby 的模型基础上巧妙使用他们构建了自己的插件系统。
- Roda源码分析(一)插件系统 4.cath和throw
比如源码的这部分
其实相当核心, 我单独介绍了一下 cath 和 throw 的使用
四、Roda 的运行流程
4.1 大致的宏观描述
Roda主要做四部分工作也对应着他的三个核心类、和一个插件系统
- class Roda
- class RodaRequest
- class RodaResponse
- Plugins
1.class Roda & Plugins
其中 class Roda 的代码非常少,主要起到一个协调和名字空间的作用。
主要的代码 在 roda/lib/roda.rb#L29 把主要的路基都放在了 module Base 中。
为什么这样做? 因为 如果在 Roda 的 class 上下文中定义自己的类方法、实例方法,会成为最高优先级,会覆盖自己的祖先类。
于是 Roda 使用了一个小技巧,把自己的 行为 封装在 Base 模块中,也当成插件 expand 进来。
这样插件也可以被 expand, 这样就可以实现 插件对 Roda 的方法进行覆盖、或者添加方法,从而实现了插件机制。
2.class RodaRequest
RodaRequest 继承自 Rack::Request 主要添加了 Roda 特色的 路由方法 route.on/is/get/post 等,还有匹配路由的适配器。
3.class RodaResponse
RodaResponse 继承自 Rack::Response
。。。。。。
写到这里,其实这篇文章比较长,然后我本来想贴在这里,可是要把引用主要是我自己博客的引用和图片,全部重弄一遍。。太麻烦了。不高兴弄了。感兴趣可以看下嘛链接,我就不重复劳动了。
我只写了 (二),因为第二部分是我自己写的多。 (一) 是引用别人多。 感兴趣可以完整的。
Roda 源码分析系列目录
我最近还保持对 Ruby和Roda的兴趣。Ruby&Roda 微信群交流: 添加 jsdhzhang 注明来意,拉你入群。