Si j'avais une déclaration if complexe que je ne voulais pas déborder simplement à des fins esthétiques, quelle serait la façon la plus casher de la casser, car coffeescript interprètera les retours comme le corps de la déclaration dans ce cas?
if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) or (not foo and not bar)
awesome sauce
else lame sauce
CoffeeScript n'interprétera pas la ligne suivante comme le corps de l'instruction si la ligne se termine par un opérateur, c'est donc ok:
# OK!
if a and
not
b
c()
il compile pour
if (a && !b) {
c();
}
afin que votre if
puisse être formaté comme
# OK!
if (foo is
bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
ou tout autre schéma de saut de ligne tant que les lignes se terminent par and
ou or
ou is
ou ==
ou not
ou un tel opérateur
Quant à l'indentation, vous pouvez indenter les non-premières lignes de votre if
tant que le corps est encore plus indenté:
# OK!
if (foo is
bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
Ce que vous ne pouvez pas faire, c'est ceci:
# BAD
if (foo #doesn't end on operator!
is bar.data.stuff and
foo isnt bar.data.otherstuff) or
(not foo and not bar)
awesome sauce
else lame sauce
Cela change quelque peu la signification de votre code, mais peut être utile:
return lame sauce unless foo and bar
if foo is bar.data.stuff isnt bar.data.otherstuff
awesome sauce
else
lame sauce
Noter la is...isnt
chaîne, qui est légitime, tout comme a < b < c
est légitime dans CoffeeScript. Bien sûr, la répétition de lame sauce
est regrettable, et vous ne voudrez peut-être pas return
tout de suite. Une autre approche consisterait à utiliser des trempages pour écrire
data = bar?.data
if foo and foo is data?.stuff isnt data?.otherstuff
awesome sauce
else
lame sauce
Le if foo and
est un peu inélégant; vous pouvez le supprimer s'il n'y a aucune chance que foo
soit undefined
.
Comme toute autre langue, en ne les ayant pas en premier lieu. Donnez des noms aux différentes parties et traitez-les séparément. Soit en déclarant des prédicats, soit en créant simplement quelques vars booléens.
bar.isBaz = -> @data.stuff != @data.otherstuff
bar.isAwsome = (foo) -> @isBaz() && @data.stuff == foo
if not bar? or bar.isAwesome foo
awesome sauce
else lame sauce
Échapper au saut de ligne me semble le plus lisible:
if (foo is bar.data.stuff and foo isnt bar.data.otherstuff) \
or (not foo and not bar)
awesome sauce
else lame sauce
Quand beaucoup de passe-partout bas se produisent, vous devez augmenter le niveau d'abstrait.
Les meilleures solutions sont:
utiliser bonnes variables et fonctions nommées
règles logiques dans les instructions if/else
L'une des règles logiques est:
(pas A et pas B) == pas (A ou B)
La première façon. Variables:
isStuff = foo is bar.data.stuff
isntOtherStuff = foo isnt bar.data.otherstuff
isStuffNotOtherStuff = isStuff and isntOtherStuff
bothFalse = not (foo or bar)
if isStuffNotOtherStuff or bothFalse
awesome sauce
else lame sauce
Le principal inconvénient de cette méthode est sa lenteur. Nous obtiendrons de meilleures performances si nous utilisons les fonctionnalités des opérateurs and
et or
et remplaçons les variables par des fonctions:
Si A
est un faux opérateur and
wouldnt appel
Si A
est un véritable opérateur or
wouldnt appel
La deuxième façon. Fonctions:
isStuff = -> foo is bar.data.stuff
isntOtherStuff = -> foo isnt bar.data.otherstuff
isStuffNotOtherStuff = -> do isStuff and do isntOtherStuff
bothFalse = -> not (foo or bar)
if do isStuffNotOtherStuff or do bothFalse
awesome sauce
else lame sauce