web-dev-qa-db-fra.com

Ruby, !! opérateur (a / k / a le double coup)

Duplicata possible:
Que signifie !! en rubis?

Salut,

Je suis nouveau à Ruby et je ne trouve aucune description de ce que signifie "!!".

Voici un exemple:

def signed_in?
  !!current_user
end

S'il s'agit d'un double négatif, pourquoi ne pas dire:

def signed_in?
  current_user
end

Veuillez aider.

92
Vitaly

Dans la plupart des langages de programmation, y compris Ruby, ! renverra l'opposé de la valeur booléenne de l'opérande. Ainsi, lorsque vous enchaînez deux points d'exclamation ensemble, il convertit la valeur en booléen.

113
icktoofay

Dans Ruby (et de nombreuses autres langues), il existe de nombreuses valeurs qui s'évaluent à true dans un contexte booléen, et une poignée qui évaluera à false. Dans Ruby, les deux seules choses évaluées à false sont false (lui-même) et nil .

Si vous niez quelque chose, cela force un contexte booléen. Bien sûr, cela le nie également. Si vous le doublez, cela force le contexte booléen, mais renvoie la valeur booléenne appropriée.

Par exemple:

"hello"   #-> this is a string; it is not in a boolean context
!"hello"  #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false)
!!"hello" #-> this is a string that is forced into a boolean 
          #   context (true), and then negated (false), and then 
          #   negated again (true)
!!nil     #-> this is a false-y value that is forced into a boolean 
          #   context (false), and then negated (true), and then 
          #   negated again (false)

Dans votre exemple, le signed_in? la méthode doit renvoyer une valeur booléenne (comme indiqué par convention par le ? personnage). La logique interne qu'il utilise pour décider de cette valeur consiste à vérifier si le current_user la variable est définie. S'il est défini, il sera évalué à true dans un contexte booléen. Sinon, il sera évalué comme faux. La double négation force la valeur de retour à être un booléen.

136
pkaeding

!! est juste ! (l'opérateur de négation booléenne) écrit deux fois. Cela annulera l'argument, puis annulera la négation. C'est utile car vous pouvez l'utiliser pour obtenir un booléen à partir de n'importe quelle valeur. La première ! convertira l'argument en booléen, par exemple true si c'est nil ou false, et false sinon. La seconde annulera cela à nouveau afin que vous obteniez la valeur booléenne de l'argument, false pour nil ou false, true pour à peu près tout le reste.

Dans Ruby vous pouvez utiliser n'importe quelle valeur dans une instruction if, par exemple if current_user s'exécutera si l'utilisateur actuel n'est pas nil. La plupart du temps, c'est génial car cela nous évite de taper des tests explicites (comme if !current_user.nil?, qui comporte au moins six caractères de plus). Mais parfois, cela peut être vraiment déroutant si vous retournez un objet lorsque la méthode implique qu'il renvoie un booléen. Méthodes dont le nom se termine par ? devrait retourner des valeurs véridiques ou fausses, c'est-à-dire qu'elles renvoient quelque chose qui sera évalué à true ou false. Cependant, cela peut devenir très compliqué si signed_in? a renvoyé un objet utilisateur. Par exemple, si vous essayez de déboguer pourquoi du code qui utilise signed_in? ne fonctionne pas, vous serez probablement très confus lorsqu'un objet utilisateur apparaîtra là où vous vous attendiez true ou false. Dans cette situation, il est utile d'ajouter !! avant le return car cela garantissait que la valeur véridique ou fausse serait retournée sous la forme true ou false.

30
Theo

Comme vous l'avez bien compris, il s'agit d'une double utilisation négative du ! opérateur. Cela dit, même si cela peut être un moyen abrégé de vérifier si une variable peut être nulle ou non, l'OMI est trop concise . Jetez un œil à this et this post. Notez que dans Ruby, tester quelque chose à zéro sera évalué à faux.

4
Zabba