这个红宝石"方法"如何运作?

dio*_*emo 2 ruby methods class object sinatra

我正在与Sinatra合作,但我对Ruby完全不熟悉并且对下面的代码实际上做了什么感到困惑.

class Something < Sinatra::Base

   get '/' do
      'hello world'
   end

end
Run Code Online (Sandbox Code Playgroud)

我们似乎没有定义方法.我们打电话给这个get方法吗?如果是这样,它什么时候被称为?我没有在其他语言中看到过这样的东西.

如果我们有2个扩展Sinatra :: Base的类,那么Sinatra如何理解它get适用于Something而不是其他类.

Ama*_*dan 10

与Java函数相反,当您在Ruby中定义类时,Ruby实际上正在执行代码.有点像Java的静态块.所以当你这样做的时候

class Foo
  puts(self)
end
Run Code Online (Sandbox Code Playgroud)

你将打开一个类(即将当前更改self为Foo),在其上下文中执行a puts(将打印出Foo类对象),然后关闭该类(返回self之前的状态).

get是一种定义的方法Sinatra::Base.因此,您的代码实际上被解释为它

class Something < Sinatra::Base
  self.get('/') do
    'hello world'
  end
end
Run Code Online (Sandbox Code Playgroud)

因为self(即Foo)继承自Sinatra::Base,这是我们正在调用的方法 - 我们Something正在读取类定义时这样做.

粗略地说,该方法的作用是保留一个"当GET请求进入时要做的事情"的表格.它记得当它看到URL时/,它应该执行该块do "hello world" end; 或多或少像这样(示例代码;原始更复杂):

class Sinatra::Base
  WHAT_TO_DO_ON_GET = {}

  def self.get(url, &thing_to_do)
    WHAT_TO_DO_ON_GET[url] = thing_to_do
  end
end
Run Code Online (Sandbox Code Playgroud)

Sinatra运行时只是一个循环,当GET请求进入时,THINGS_TO_DO_ON_GET它会查找URL 并执行它在那里找到的内容.