Mark24
记录灵感、技术、思考
sinatra文档连接
一、模块化路由
比较好的方式定义模块的方式
定义一个模块
require 'sinatra/extension'
module DemoController
extend Sinatra::Extension
get '/' do
json({
message: 'hello world'
})
end
end
使用一个模块
class Application < Sinatra::Base
register DemoController
end
比较全面的总结:
拓展原理
helpers、register (以及registered) 具体作了什么
# helpers
def helpers(*extensions, &block)
class_eval(&block) if block_given?
include(*extensions) if extensions.any?
end
# register
def register(*extensions, &block)
extensions << Module.new(&block) if block_given?
@extensions += extensions
extensions.each do |extension|
extend extension
extension.registered(self) if extension.respond_to?(:registered)
end
end
总结
-
具体用了什么 helpes 背后是 include 和 class_eval。 他的特点在于共享class上下文。 register 背后就是 extend,简而言之就是单例方法插入方法。
- 本质意义
-
Ruby中include / extend / prepend的区别: include: 把模块注入目标类或者模块作为实例方法 extend: 把模块注入目标类或者模块作为类方法(Singleton Method) prepend: 同样把模块注入目标类或者模块作为实例方法,和include的区别是把模块的方法放在了目标类或者模块方法调用链的前边,对比 B 和 C 的继承链。
- 官方概述 因为是 include 所以运行在实例之中,所以在Sinatra的描述中,helpers 函数运行在 request 的上下文 router、view、helpers中
helpers 是拓展 request的上下文
register 是拓展 Sinatra本身的 DSL(Class内置语法,比如和get、set同级别)
registered方法,运行在 register之后,区别在于 传递了 app 实例,可以作很多事情。
参考
include
当一个类或者模块 include 了一个 module M 时, 则该类或者模块就拥有了该 module M 的方法。
当涉及多个类调用同一方法时,这个方法就可以抽离出来,放入 module 中,然后类只需 include 该 module 即可。这样的做法也正体现了 DRY 原则。
extend
当一个类或者对象使用 extend 时,相当于打开了该类或者该对象的单件类,为其添加了单件方法。