L'utilisation de «ou» est dangereuse. 'ou' a une présence inférieure à l'opérateur = ', donc le comportement suivant est inattendu: a = false ou true #a est faux après cette déclaration
Tom G
20
@xiy actuellement le guide recommande de faire semblant ou et et n'existent pas (|| est-ce ou && et?)
user3125280
67
Présente "Ruby Style Guide" The and and or keywords are banned. It's just not worth it. Always use && and || instead.. Et c'est vrai, pour des raisons de David et Tom.
Andre Figueiredo
40
classObjectdef nil_zero?self.nil?||self==0endend# which lets you donil.nil_zero?# returns true0.nil_zero?# returns true1.nil_zero?# returns false"a".nil_zero?# returns falseunless discount.nil_zero?# do stuff...end
Méfiez-vous des avertissements habituels ... grande puissance / responsabilité, correction de singe menant au côté obscur, etc.
Notez qu'il s'agit d'une réponse spécifique aux rails . Le rubis vanille n'a pas de tryméthode.
Tom Lord
Correct. Bien qu'il ressemble davantage à ActiveSupport, qui est une dépendance beaucoup plus légère et largement utilisée que les rails complets. Quoi qu'il en soit, la réponse de @ ndn est la bonne.
réécrit le
Modifié pour utiliser la navigation en toute sécurité
réécrit le
1
La réponse duplique maintenant stackoverflow.com/a/34819818/1954610 ... Je pense qu'il est utile de la laisser trypour montrer l'option alternative (c'est pourquoi elle a été votée en premier lieu!), Tant qu'il est clair le lecteur qui ActiveSupportn'est pas du rubis vanille.
Je trouve cela parfaitement lisible, et je le préférerais à une nouvelle classe. Bien joué.
colincr
L'approche la plus rubyiste de gérer deux conditions.
Yugendran
23
À partir de Ruby 2.3.0, vous pouvez combiner l'opérateur de navigation sécurisée ( &.) avec Numeric#nonzero?. &.renvoie nilsi l'instance était nilet nonzero?- si le nombre était 0:
"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String.... Ce n'est pas sûr à utiliser sur des objets arbitraires.
Tom Lord
2
@TomLord, comme indiqué dans le commentaire précédent, cela n'était pas destiné à fonctionner avec des objets arbitraires. Au lieu de cela, il s'agit du cas où vous avez quelque chose que vous savez être un nombre, mais qui pourrait aussi l'être nil.
ndnenkov
Je voudrais que ce fait soit clair dans la réponse, plutôt que quelqu'un le lisant et ne repérant pas l'avertissement dans les commentaires.
Tom Lord
@TomLord, c'est indiqué dans la réponse " nonzero?- si le nombre était 0" . De même, la nécessité de vérifier si un objet complètement arbitraire se 0pose est extrêmement rarement comparée à celle de vérifier un nombre qui peut ou non l'être nil. Elle est donc presque implicite. Même si quelqu'un fait en quelque sorte l'hypothèse contraire, il comprendra instantanément ce qui se passe lorsqu'il essaie de l'exécuter.
L'ordre est important ici, car s'il l' discountest nil, alors il n'aura pas de zero?méthode. L'évaluation des courts-circuits de Ruby devrait cependant l'empêcher d'essayer d'évaluer discount.zero?si discountc'est le cas nil.
N'est-ce pas la même chose que la réponse de @ oivoodo?
Cary Swoveland,
Ne fonctionne pas pour les objets arbitraires . "".to_i == "foo".to_i == "0".to_i == 0. Votre méthode créera toutes sortes de contraintes de type non intentionnelles. Il échouera également avec un NoMethodErrorsi discountne répond pas to_i.
Tom Lord
2
def is_nil_and_zero(data)
data.blank?|| data ==0end
Si nous passons "" il retournera faux alors vide? renvoie vrai. Il en va de même lorsque data = false blank? renvoie true pour nil, false, vide ou une chaîne d'espaces. Il est donc préférable d'utiliser des blancs? pour éviter également les chaînes vides.
Vous pouvez initialiser la remise à 0 tant que votre code est garanti de ne pas essayer de l'utiliser avant son initialisation. Cela supprimerait un chèque, je suppose, je ne peux penser à rien d'autre.
Je crois que ce qui suit est assez bon pour le code ruby. Je ne pense pas que je pourrais écrire un test unitaire qui montre une différence entre cela et l'original.
discount
c'est faux?discount.in? [0, nil]
la façon la plus propre possibleRéponses:
la source
The and and or keywords are banned. It's just not worth it. Always use && and || instead.
. Et c'est vrai, pour des raisons de David et Tom.Méfiez-vous des avertissements habituels ... grande puissance / responsabilité, correction de singe menant au côté obscur, etc.
la source
ok, après 5 ans se sont écoulés ....
Il est important de noter qu'il
try
est défini dans la gemme ActiveSupport, il n'est donc pas disponible en rubis uni.la source
try
méthode.try
pour montrer l'option alternative (c'est pourquoi elle a été votée en premier lieu!), Tant qu'il est clair le lecteur quiActiveSupport
n'est pas du rubis vanille.la source
À partir de Ruby 2.3.0, vous pouvez combiner l'opérateur de navigation sécurisée (
&.
) avecNumeric#nonzero?
.&.
renvoienil
si l'instance étaitnil
etnonzero?
- si le nombre était0
:Ou suffixe:
la source
"foo"&.nonzero? # => NoMethodError: undefined method 'nonzero?' for "foo":String
.... Ce n'est pas sûr à utiliser sur des objets arbitraires.nil
.nonzero?
- si le nombre était0
" . De même, la nécessité de vérifier si un objet complètement arbitraire se0
pose est extrêmement rarement comparée à celle de vérifier un nombre qui peut ou non l'êtrenil
. Elle est donc presque implicite. Même si quelqu'un fait en quelque sorte l'hypothèse contraire, il comprendra instantanément ce qui se passe lorsqu'il essaie de l'exécuter.la source
Vous pouvez faire ceci:
L'ordre est important ici, car s'il l'
discount
estnil
, alors il n'aura pas dezero?
méthode. L'évaluation des courts-circuits de Ruby devrait cependant l'empêcher d'essayer d'évaluerdiscount.zero?
sidiscount
c'est le casnil
.la source
Vous pouvez convertir votre ligne vide en valeur entière et vérifier zéro?.
la source
mise à jour, il sera
false
pourdiscount = false
la source
Vous pouvez profiter de la méthode
NilClass
fournie#to_i
, qui renverra zéro pour lesnil
valeurs:S'il
discount
peut s'agir de nombres fractionnaires, vous pouvez utiliser à la#to_f
place, pour éviter que le nombre ne soit arrondi à zéro.la source
"".to_i == "foo".to_i == "0".to_i == 0
. Votre méthode créera toutes sortes de contraintes de type non intentionnelles. Il échouera également avec unNoMethodError
sidiscount
ne répond pasto_i
.Si nous passons "" il retournera faux alors vide? renvoie vrai. Il en va de même lorsque data = false blank? renvoie true pour nil, false, vide ou une chaîne d'espaces. Il est donc préférable d'utiliser des blancs? pour éviter également les chaînes vides.
la source
blank?
est une méthode spécifique aux rails et non disponible en rubis vanille.Lorsque je traite un enregistrement de base de données , j'aime initialiser toutes les valeurs vides avec 0, en utilisant l'aide à la migration:
la source
Vous pouvez initialiser la remise à 0 tant que votre code est garanti de ne pas essayer de l'utiliser avant son initialisation. Cela supprimerait un chèque, je suppose, je ne peux penser à rien d'autre.
la source
la source
Je préfère utiliser une approche plus propre:
val.to_i
renverra un0
si val est unnil
,après cela, tout ce que nous devons faire est de vérifier si la valeur finale est un zéro .
la source
La solution alternative consiste à utiliser les raffinements, comme ceci:
la source
Je crois que ce qui suit est assez bon pour le code ruby. Je ne pense pas que je pourrais écrire un test unitaire qui montre une différence entre cela et l'original.
la source
true
si la remise étaitnil
.