大家好,我是 MARK24。可以叫我 MARK。这是我研究 Roda,做的记录。水平有限,欢迎指正。
研究的 Roda 源码版本 2022 年 2 月 9 日 Roda v3.52.0 dc600b763ebf4f15e11c0428e26b812b9d140911
阅读本文章,你可能获得
以及欣赏 Roda 的设计等。
我个人水平和精力有限,研究 Ruby 时间不长,自认还是个小学生。如有错误欢迎指正,欢迎交流~
熟悉的可以跳过 Rack 部分。
Roda 本质上还是有一个 Rack 的应用。用户请求发送至我们的服务器,首先经过 Rack,所以先要明白 Rack 的工作原理。
这篇文章简单的介绍了 Rack 的工作流程
想要深入了解 Rack 可以查看官网源码
有一部国人编写的笔记也可以提供很大的帮助,可以下载:【RackProgram.pdf
】 (走我的博客吧,不方便再搞一遍了:Roda 源码分析 (二) 请求响应 )
Roda 只是一个研究对象,研究方法是通用的。
1.把握宏观,要分清楚几个大类,每个方法在哪个大类下工作,决定了理解他们的角色
大概只需要关注,大类、和 initialize 方法。这里决定了他们初始化的值。
可以理解未来都是围绕着 initialize 里面的数据。
2.从入口开始往上找调用方法看看调用关系
阅读代码不应该从代码层面的 从上往下读。这是错误的。
根据语言的运行特点,以 Ruby 为例。应该以 解释器或者编译的运行顺序来观察源码。
1)代码初始化,进行了什么
class 类声明、以及类中可执行语句在运行。可以关注下 class 中 initialize 中声明的变量,以及动态生成的代码。(Ruby 和其他语言不一样,class 内部也有代码在运行,你应该知道的。)
2) 入口开始,调用关系
建立完内存中初始化的 class 等对象。就可以站在程序运行的角度,从入口调用的顺序 依次查看源码。
3.分析工具
主要使用他们的一些功能帮助阅读。有人可能觉得 DEBUG 工具就够了,我的体会不是这样,DBEUG 的切入点太细碎,而且不够准(我总是这个感觉)。跳转的地方往往涉及面太广,出错了要再次重来。当然可能我不会用啦。不过这些不重要。
真正重要的部分其实是明白 Ruby 工作的机制,以及按照 Ruby 运行的规律,去解读源码的主要部分,识别作者的意图。我觉得这个才比较重要。
1)VScode 编辑器
2)RubyMine(或者一款 IDE)
3) 草稿纸
记录重要的引用关系,记录分析和思考。
1.class 的上下文中,attr 语句会执行、@语句会执行、def 语句会注册但是不会执行(实例化被实例调用执行),class 上下文的 define_method 会执行
2.def 首次运行只注册不允许,具体的 def 的方法调用顺序,根据 启动 app 的顺序依次调用
3.Ruby 的对象模型,以及 extend、include
这部分主要看插件系统好了。作者在 Ruby 的模型基础上巧妙使用他们构建了自己的插件系统。
比如源码的这部分
其实相当核心,我单独介绍了一下 cath 和 throw 的使用
Roda 主要做四部分工作也对应着他的三个核心类、和一个插件系统
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
。。。。。。
写到这里,其实这篇文章比较长,然后我本来想贴在这里,可是要把引用主要是我自己博客的引用和图片,全部重弄一遍。。太麻烦了。不高兴弄了。感兴趣可以看下嘛链接,我就不重复劳动了。
我只写了(二),因为第二部分是我自己写的多。 (一)是引用别人多。感兴趣可以完整的。