7
votes

Pourquoi est-ce que célibataire `=` travaille dans `if` énoncé?

Ce code est fourni à titre d'exemple à utiliser avec le Devise et Omniauth, il fonctionne dans Mon projet .

class User < ActiveRecord::Base
  def self.new_with_session(params, session)
    super.tap do |user|
      if data = session["devise.facebook_data"] && session["devise.facebook_data"]["extra"]["raw_info"]
        user.email = data["email"] if user.email.blank?
      end
    end
  end
end


0 commentaires

4 Réponses :


2
votes

dans Ruby, un seul signe égal est utilisé pour affectation . L'expression xxx

attribue le résultat de l'évaluation de la session ["devise.facebook_data"] à une variable locale nommée data

si la session hachage n'a pas de "devise.facebook_data" clé , il retournera nil et données sera attribué nil . Les affectations évaluent à la valeur étant attribuée, la mission évaluera donc à nil aussi. NIL est considéré comme un faux dans un contexte booléen, de sorte que le bon opérancier du && ne sera pas évalué. De cette façon, vous n'obtiendrez pas un nométhoderror nil ["extra"] ["Raw_info"] .

si le SESSION HASH Est-ce que a un "" devise.facebook_data " clé, data sera défini sur la valeur associée à celle-ci. Toute valeur autre que nil et false est considérée comme une vérité, donc l'opérande de droite de l'opérateur && sera évalué.

Si la condition est en vérité, la clause sera évaluée, qui utilise la variable DATA attribué à la condition.


Remarque: Je pense que l'on pourrait également utiliser la variable de données dans le côté droit de l'opérateur && , c'est-à-dire que la condition pourrait lire comme ceci à la place: < Pré> xxx

mais je vais devoir vérifier cela.


2 commentaires

Oui, c'est ce que je pensais, je suppose que je suis juste confondu par la mise en page de la fonction. Pourriez-vous éventuellement expliquer ce que c'est exactement demandé? Je vois le &&, mais il semble que ça va plus que ça?


Le premier si est équivalent à data = ... suivi de si des données; utilisateur.email = ... .



1
votes

Un opérateur d'affectation ( = ) renvoie la valeur attribuée, qui est ensuite évaluée par le si . En rubis, seul faux et nil est considéré comme faux . Tout le reste évalue à true dans un contexte booléen (comme un si ).


0 commentaires

0
votes

Ruby ne se soucie pas des types de conditionnels, contrairement à Java. Tant que la valeur n'est ni née ni fausse, elle passera.

Dans votre exemple, vous discriminez-vous réellement contre NIL: le si subordonné que les données n'existent pas et ne sont pas nulles, nous pouvons donc l'utiliser, en supposant que c'est un hachage. Ceci est un modèle commun dans Ruby.


1 commentaires

En réalité, une valeur est faluée ou non est déterminée par son type (classe) , c'est-à-dire s'il s'agit d'une instance de nilclass ou falseclass , alors c'est falueux.



7
votes

La seule chose nécessaire à un si instruction à être valide est une expression booléenne. Dans ce cas, étant donné que = renvoie le résultat de la mission, ce qui est réellement testé est la falsification de la session ["devise.facebook_data"] .

intelligy a un Bon point pour déposer une plainte sur le code comme celui-ci, car il est difficile de lire sans connaître une chose ou deux sur Ruby. Une recommandation serait de le déplacer à une déclaration d'affectation explicite à la place. Cela a l'avantage supplémentaire de sécher une référence à deux fois. xxx


3 commentaires

Merci!! A du sens maintenant, vous avez expliqué cela parfaitement.


Je ne sais pas ce que vous entendez par "chose nécessaire ... être valide est une expression booléenne". Tout objet peut apparaître après si . Existe-t-il un objet "non booléen" que vous avez à l'esprit que vous feriez un si condition illégale?


@sawa quand je suis près d'une machine, je peux réviser cette partie.