13 votes

rails/ruby syntaxe "and return false" (et retourner faux)

J'ai vu ce code dans un tutoriel sur les rails que je suis en train de réaliser.

def access_denied
  redirect_to login_path, :notice => "Please log in to continue" and return false
end

Avant d'apprendre rails, j'ai fait une grande quantité de recherches sur ruby et aucun des livres que j'ai lus ne couvrait cette syntaxe "and return false" qui se passe ici. Je ne trouve aucune mention de cette syntaxe dans la syntaxe de rails. Quelqu'un peut-il fournir un lien ou une explication qui permettrait de clarifier ce point ?

Je ne comprends pas la nécessité du "et" ici car je pensais que Ruby retournerait toujours la dernière expression évaluée.

24voto

Maurício Linhares Points 19468

El y est là uniquement pour que vous puissiez écrire la retournez à la case départ à la même ligne que la déclaration précédente.

C'est l'équivalent de faire ça :

redirect_to login_path, :notice => "Please log in to continue"
return false

ce n'est pas exactement la même chose parce qu'avec le "et", il ne retournerait que false si le redirect_to retourne quelque chose qui n'est pas néant o faux mais comme il retourne presque toujours quelque chose qui n'est pas néant ni faux alors le côté droit de l'instruction est toujours exécuté (et faux est renvoyé).

El y en Ruby est juste un alias de && et se comporte exactement comme elle, à une seule différence près : elle a une priorité inférieure à celle de tous les autres éléments de l'instruction, de sorte qu'elle évalue d'abord ce qui se trouve à sa gauche, puis est appliquée. Ruby dispose également de la fonction ou qui est identique à || mais avec une préséance inférieure dans les expressions.

3voto

maprihoda Points 5600

redirect_to login_path, :notice => "Please log in to continue" est une expression normale en Ruby qui ne renvoie pas false (ou nil, voir la fonction code source ), l'exécution du programme se poursuit donc (pour vérifier la deuxième partie après AND) et return false peut être exécuté.

2voto

Dave Newton Points 93112

Ce type de construction était autrefois utilisé avec un filtre, lorsque les valeurs de retour du filtre étaient attendues. Le site false interromprait le traitement normal des demandes.

Donc si un contrôleur ressemblait à ça :

class FooController < ActionController::Base
  before_filter :access_denied
  # etc.
end

Aucune des actions du contrôleur ne s'exécuterait ; cette méthode a probablement été conçue pour être appelée de un filtre, comme :

def check_access
  return access_denied unless current_user.has_access
end

De nos jours, les valeurs de retour des filtres sont ignorées.

Il pourrait être utilisé comme une méthode normale dans une action pour arrêter le traitement de l'action et revenir après la redirection, de sorte qu'aucune autre logique/rendu/etc. ne soit exécutée dans le contrôleur.

1voto

iWasRobbed Points 26926

Documentation sur les opérateurs : Sous la section "Défini ?, Et, Ou, et Non".

Utilisation de and est utile pour enchaîner des opérations connexes jusqu'à ce que l'une d'entre elles renvoie l'information. nil o false . Vous pouvez l'utiliser comme vous l'avez montré dans votre question ou vous pouvez également l'utiliser pour court-circuiter la ligne de code.

# Short circuit example
blog = Blog.find_by_id(id) and blog.publish! 

Le blog ne reçoit que .publish! appelé sur lui si le find_by_id a réussi.

Dans votre exemple :

def access_denied
  redirect_to login_path, :notice => "Please log in to continue" and return false
end

Ils l'utilisent simplement pour écrire le code de manière plus compacte sur une seule ligne.

Cependant, elle est également utile pour une action de contrôleur où vous pouvez effectuer un rendu basé sur des conditionnels et où vous ne voulez pas recevoir l'avertissement de Rails "multiple renders" :

def show
  if something
    render :partial => 'some_partial'
  end

  render :partial => 'some_other_partial'
end

Rails vous donnera un avertissement si something renvoie vrai puisque vous avez plusieurs instructions de rendu évaluées dans l'action. Cependant, si vous le changez en

if something
  render :partial => 'some_partial' and return
end

cela vous permettrait d'arrêter l'exécution de l'action.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X