我遇到了sinatra条件方法,对它的工作原理感到困惑。
我有一段代码:
def auth user
condition do
redirect '/login' unless user_logged_in?
end
end
它检查用户是否记录了某些路由,例如路由:
get '/', :auth => :user do
erb :index
end
方法
user_logged_in?
是在项目的lib目录中的helper文件中定义的:def user_logged_in?
if session[:user]
@user = session[:user]
return @user
end
return nil
end
所以,问题是:
当
condition
路径上的session[:user]
尚未设置时,get '/'
块如何知道session[:user]
包含什么?condition
方法在下面的github页面中定义:sinatra base condition method谢谢。
最佳答案
定义路由时,options散列的每个成员的键都是called as a method, with the value passed as the arguments。
因此,当您执行get '/', :auth => :user do ...
操作时,方法auth
将使用参数:user
调用。这反过来调用带有块的condition
方法。condition
方法实际上是defined just above where you link to方法的一种用法。看起来是这样的:
def condition(name = "#{caller.first[/`.*'/]} condition", &block)
@conditions << generate_method(name, &block)
end
generate_method
方法将块转换为具有给定名称的方法,然后将此方法保存在@conditions
数组中。@conditions
的内容随后与路由定义一起保存,并清除@conditions
以准备下一个路由定义。此时,传递给
condition
的代码块尚未执行。它实际上已经被保存了下来,以备日后使用。当实际请求进入时,如果请求路径与路由匹配,则each condition associated with that route is executed检查是否已完成。在本例中,这是首次执行
redirect '/login' unless user_logged_in?
时,因此session
将已设置并且session[:user]
将可用(如果它们未登录,则不可用)。了解这一点的重要一点是,当您将一个块传递给一个方法时,该块中的代码不一定立即被调用。在这种情况下,块中的代码只在实际请求到达时调用。