最近碰巧在 Ruby 代码中看到了这个词use
,当时我正在浏览一些与goliath、中间件等相关的代码。看起来它与include
/extend
和. 不同require
。
有人可以解释为什么这个use
关键字存在,以及它与include
/有何不同require
?它是如何工作的,何时使用?
最近碰巧在 Ruby 代码中看到了这个词use
,当时我正在浏览一些与goliath、中间件等相关的代码。看起来它与include
/extend
和. 不同require
。
有人可以解释为什么这个use
关键字存在,以及它与include
/有何不同require
?它是如何工作的,何时使用?
正如人们所指出的,use
它不是 Ruby 关键字,它实际上是Rack::Builder
类的方法:
use(middleware, *args, &block)
指定要在堆栈中使用的中间件。
该文档(由@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
源代码不太熟悉,但是看起来每次您use
使用新的中间件模块调用时,它都会被添加到数组中,并且每个模块都以添加的相反顺序运行/注入(最后-in-first-out order,又称堆栈顺序)。运行前一个中间件的结果通过以下方式传递给堆栈中的下一个中间件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