最近、 goliathやミドルウェアなどにuse
関連するコードを調べていたときに、Ruby のコードで ,という言葉をたまたま目にしました。include
extend
require
use
このキーワードが存在する理由と、 include
/との違いを誰かが説明できますかrequire
? どのように機能し、いつ使用するのですか?
最近、 goliathやミドルウェアなどにuse
関連するコードを調べていたときに、Ruby のコードで ,という言葉をたまたま目にしました。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 オーダー、別名スタック オーダー)。前のミドルウェアを実行した結果は、次の経由でスタック内の次のミドルウェアに渡されます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