2012-01-21 3 views
6

Je suis tombé sur la méthode sinatra condition et je suis intrigué dans la façon dont cela fonctionne.Que fait réellement Sinatra :: Base.condition?

I ont un morceau de code:

def auth user 
    condition do 
    redirect '/login' unless user_logged_in? 
    end 
end 

qui vérifie si un utilisateur est connecté pour certaines routes, une route par exemple:

get '/', :auth => :user do 
    erb :index 
end 

La méthode user_logged_in? est définie dans un assistant fichier dans le répertoire lib du projet:

def user_logged_in? 
    if session[:user] 
    @user = session[:user] 
    return @user 
    end 
    return nil 
end 

Donc, la question est: Comment le bloc condition sait-il ce que contient le session[:user], alors que sur l'itinéraire get '/' le session[:user] n'a même pas été défini?

La méthode condition est définie dans la page GitHub suivante: sinatra base condition method Merci.

Répondre

4

Lorsque vous définissez un itinéraire, la clé de chaque membre du hachage d'options est called as a method, with the value passed as the arguments.

Ainsi, lorsque vous faites get '/', :auth => :user do ..., la méthode auth est appelée avec l'argument :user. Cela à son tour appelle la méthode condition avec le bloc.

La méthode condition est en fait defined just above where you link to qui est une utilisation. Il ressemble à ceci:

def condition(name = "#{caller.first[/`.*'/]} condition", &block) 
    @conditions << generate_method(name, &block) 
end 

La méthode generate_method convertit le bloc en une méthode avec le nom donné, et cette méthode est enregistrée dans le tableau @conditions. Le contenu de @conditions est alors sauvegardé avec la définition de l'itinéraire, et @conditions est effacé pour la prochaine définition d'itinéraire.

À ce stade, le bloc de code transmis à condition n'a pas été exécuté. Il a en effet été enregistré pour plus tard.

Lorsqu'une requête réelle arrive, si le chemin de la requête correspond à l'itinéraire, alors each condition associated with that route is executed pour vérifier qu'il est rempli. Dans cet exemple, c'est lorsque redirect '/login' unless user_logged_in? est exécuté pour la première fois, donc session aura été configuré et session[:user] sera disponible (ou non s'ils ne sont pas connectés). La chose importante à comprendre à ce sujet est que lorsque vous passez un bloc à une méthode, le code de ce bloc n'est pas nécessairement appelé immédiatement.Dans ce cas, le code dans le bloc n'est appelé que lorsqu'une requête réelle arrive.

+0

je vous remercie beaucoup pour une explication prudente. Mes compétences en lecture Ruby ont été totalement perplexes lorsque j'ai regardé la méthode 'condition'. Même si la lecture du code me semble toujours très douloureuse, vous m'avez permis de comprendre ce qui se passe. À votre santé. –

2

Parce que Sinatra est responsable de l'appel des méthodes de condition et des méthodes de routage. Par conséquent, il devrait être prudent de supposer que tout ce qui est défini lorsque votre méthode de route est exécutée est également défini lorsque votre condition est exécutée.

Regardez le code commençant par here: les conditions sont appelées une par une; Si toutes les conditions correspondent, le bloc est appelé. Il ne se passe pas grand-chose entre la vérification des conditions et l'appel du bloc: elles sont essentiellement exécutées dans le même contexte.

+0

Merci pour cela, @matt a pu montrer ce qui se passe dans le contexte de mon programme, et c'est ce que je recherchais. –

Questions connexes