最近我碰巧在Ruby代码use
中看到这个词,当我浏览一些与goliath相关的代码,中间件等时看起来它与include
/不同extend
和require
。
有人可以解释为什么这个use
关键字存在,以及它与include
/ require
的区别?它是如何工作的,什么时候使用它?
答案 0 :(得分:27)
正如人们所指出的,use
不是Ruby关键字,它实际上是Rack::Builder
class的一种方法:
<强>
use(middleware, *args, &block)
强>指定要在堆栈中使用的中间件。
This documentation(pointed out by @user166390)就像这样描述:
Rack::Builder
实现了一个小型DSL,以迭代方式构建Rack
个应用程序。示例:
app = Rack::Builder.new { use Rack::CommonLogger use Rack::ShowExceptions map "/lobster" do use Rack::Lint run Rack::Lobster.new end }
或者
app = Rack::Builder.app do use Rack::CommonLogger lambda { |env| [200, {'Content-Type' => 'text/plain'}, 'OK'] } end
use
向堆栈添加中间件,run
将调度到应用程序。
我对Rack::Builder
source code不太熟悉,但看起来每次使用新的中间件模块调用use
时,它都会被添加到数组中,并且每个模块都会运行/注入以相反的顺序添加它(后进先出顺序,也就是堆栈顺序)。运行上一个中间件的结果通过inject
传递给堆栈中的下一个中间件:
def initialize(default_app = nil,&block)
# @use is parallel assigned to [].
@use, @map, @run = [], nil, default_app
instance_eval(&block) if block_given?
end
def use(middleware, *args, &block)
if @map
mapping, @map = @map, nil
@use << proc { |app| generate_map app, mapping }
end
# The new middleware is added to the @use array.
@use << proc { |app| middleware.new(app, *args, &block) }
end
def to_app
app = @map ? generate_map(@run, @map) : @run
fail "missing run or map statement" unless app
# The middlewares are injected in reverse order.
@use.reverse.inject(app) { |a,e| e[a] }
end