2012-03-05 20 views
43

Sono principalmente uno sviluppatore Rails, e così in montare un piccolo script per esempio Hubot della mia azienda, speravo di realizzare i seguenti:Coffeescript || = analogico?

robot.brain.data.contacts ||= {} 

Oppure, solo a rendere questo nuovo hash se doesn' già esiste L'idea è che voglio avere un array di contatti aggiunto dinamicamente attraverso lo script, quindi non devo modificare il sorgente di Hubot, e ovviamente non voglio sovrascrivere nessun contatto che aggiungo ad esso.

Domanda: c'è un piccolo costrutto veloce come Rails || = che posso usare in Coffeescript per raggiungere l'obiettivo di cui sopra?

Cheers.

risposta

61

È possibile utilizzare ?= per l'assegnazione condizionale:

speed ?= 75 

Il ? è il "esistenziale operatore" in CoffeeScript, in modo che metterà alla prova per l'esistenza (non truthiness):

if (typeof speed === "undefined" || speed === null) speed = 75; 

Il JS risultante è un po 'diverso nel tuo caso, però, perché stai testando un oggetto rty, non solo una variabile, quindi robot.brain.data.contacts ?= {} genera il seguente:

var _base, _ref; 
if ((_ref = (_base = robot.brain.data).contacts) != null) { 
    _ref; 
} else { 
    _base.contacts = {}; 
}; 

Maggiori informazioni: http://jashkenas.github.com/coffee-script/

7

?= assegnerà una variabile se è null o undefined.

Usalo come speed ?= 25

4

Si chiama l'operatore esistenziale in CoffeeScript ed è ?=, http://coffeescript.org/. Citando qui di seguito:

esistenziale operatore

E 'un po' difficile da verificare l'esistenza di una variabile in JavaScript. se (variabile) si avvicina, ma fallisce per zero, la stringa vuota e false. L'operatore esistenziale di CoffeeScript? restituisce true a meno che una variabile sia nullo o indefinito, il che lo rende analogo a Ruby zero?

Può anche essere utilizzato per un'assegnazione condizionale più sicura di || = , per i casi in cui è possibile gestire numeri o stringhe.

12

io personalmente uso or= invece di ?= soprattutto perché questo è quello che io chiamo ||= (o uguale) quando lo uso in Ruby.

robot.brain.data.contacts or= {} 

La differenza è che or= cortocircuiti quando robot.brain.data.contacts non è null, considerando ?= test per null e imposta solo robot.brain.data.contacts a {} se non null.

See the compiled difference.

Come accennato in un altro post, nessuno dei due metodi verifica l'esistenza di robot, robot.brain o robot.brain.data, ma neppure l'equivalente di Ruby.

Edit:

Inoltre CoffeeScript or= e ||= compilare allo stesso JS.

+1

'o =' e '? =' non compila sullo stesso JS. '? =' esegue un controllo nullo. Vedi [this] (http://coffeescript.org/#try:a%20%3D%20b%20%3D%200%0A%0Aa%20or%3D%201%3B%0Ab%20%3F%3D% 201% 3B) per la differenza quando si utilizzano nomi di variabili diversi. –

1

Il dialetto Coco di CoffeeScript, http://github.com/satyr/coco, supporta matrice e oggetti operatori autovivificazione @ e @@:

[email protected]@[email protected] = 1 

compila in - concesso, peloso dall'aspetto -

var _ref, _ref2; 
((_ref = (_ref2 = robot.brain || (robot.brain = {})).data || (_ref2.data = {})).contacts || (_ref.contacts = {})).foo = 1; 

che assicura che ogni A proposito, robot.brain, brain.data, data.contacts esiste effettivamente.

Naturalmente si potrebbe desiderare solo l'opera di fatto condizionale di assegnazione (che, secondo le risposte di cui sopra, esiste anche in CoffeeScript):

robot.brain.data.contacts ?= {} 

che compila

var _ref; 
(_ref = robot.brain.data).contacts == null && (_ref.contacts = {});