Подтвердить что ты не робот

"использовать" ключевое слово/слово в Ruby/Rails/Rack code

Недавно мне довелось увидеть это слово в коде Ruby, use, когда я просматривал какой-то код, относящийся к goliath, промежуточное программное обеспечение и т.д. Похоже, что он отличается от include/extend и require.

Может кто-нибудь объяснить, почему это ключевое слово use существует и как оно отличается от include/require? Как это работает, когда его использовать?

4b9b3361

Ответ 1

Документация

Как отмечают люди, 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 с помощью новый модуль промежуточного программного обеспечения, он добавляется в массив, и каждый модуль запускается/вводится в обратном порядке, в котором он был добавлен (порядок "последний-в-первом-порядке", так называемый порядок стека). Результат запуска предыдущего промежуточного программного обеспечения передается следующему промежуточному программному обеспечению в стеке через inject:

  • Строки 53-56:

    def initialize(default_app = nil,&block)
      # @use is parallel assigned to [].
      @use, @map, @run = [], nil, default_app
      instance_eval(&block) if block_given?
    end
    
  • Строки 81-87:

    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
    
  • Линии 131-135:

    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
    

Дополнительные ресурсы