Sinatra如何定义和调用get方法?

mko*_*mko 7 ruby metaprogramming sinatra

我对这件事的运作方式很好奇.

在要求'sinatra'之后

然后我可以在顶级范围内调用get().

在深入研究源代码后,我发现了这个get()结构

module Sinatra
 class << self
   def get
    ...
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

知道类<< self是打开self对象的单例类定义并在里面添加get(),所以它开始有意义.

但唯一遗漏的是我无法理解的是它在模块Sinstra中,如何在不使用Sinatra :: resolution操作的情况下调用get()?

jer*_*son 10

它分散在几个地方,但如果你查看lib/sinatra/main.rb,你可以在底部看到这一行: include Sinatra::Delegator

如果我们进入,lib/sinatra/base.rb我们会看到像1470这样的代码块.

  # Sinatra delegation mixin. Mixing this module into an object causes all
  # methods to be delegated to the Sinatra::Application class. Used primarily
  # at the top-level.
  module Delegator #:nodoc:
    def self.delegate(*methods)
      methods.each do |method_name|
        define_method(method_name) do |*args, &block|
          return super(*args, &block) if respond_to? method_name
          Delegator.target.send(method_name, *args, &block)
        end
        private method_name
      end
    end

    delegate :get, :patch, :put, :post, :delete, :head, :options, :template, :layout,
             :before, :after, :error, :not_found, :configure, :set, :mime_type,
             :enable, :disable, :use, :development?, :test?, :production?,
             :helpers, :settings
    class << self
      attr_accessor :target
    end

    self.target = Application
  end
Run Code Online (Sandbox Code Playgroud)

此代码执行注释所说的内容:如果包含它,它会将对委托方法列表的所有调用委托给Sinatra::Applicationclass,class是子类Sinatra::Base,也get就是定义方法的位置.当你写这样的东西:

require "sinatra"

get "foo" do
  "Hello World"
end
Run Code Online (Sandbox Code Playgroud)

由于之前建立的授权,Sinatra最终会调用该get方法Sinatra::Base.