2012-03-05 12 views
43

soy principalmente un desarrollador Rails, y así, en azotar encima de un pequeño script por ejemplo hubot de mi empresa, yo tenía la esperanza de lograr lo siguiente:Coffeescript || = analógico?

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

O, sólo se crea este nuevo hash de si él doesn' t ya existe. La idea es que quiero tener una matriz de contactos agregada dinámicamente a través de la secuencia de comandos para no tener que modificar la fuente de Hubot, y obviamente no quiero sobrescribir ningún contacto que agregue a ella.

Pregunta: ¿hay un pequeño y rápido constructo como los Rails || = que puedo usar en Coffeescript para lograr el objetivo anterior?

Saludos.

Respuesta

61

Puede utilizar ?= para la asignación condicional:

speed ?= 75 

El ? es el "existencial del operador" en CoffeeScript, por lo que la prueba de la existencia (no truthiness):

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

El JS resultante es un poco diferente en su caso, sin embargo, porque está probando un objeto prope rty, no sólo una variable, por lo robot.brain.data.contacts ?= {} resultados en la siguiente:

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

Más información: http://jashkenas.github.com/coffee-script/

7

?= asignará una variable si es null o undefined.

Se usa como speed ?= 25

4

Se llama el operador existencial en CoffeeScript y es ?=, http://coffeescript.org/. Citando a continuación:

El operador existencial

Es un poco difícil de comprobar la existencia de una variable en JavaScript. if (variable) se acerca, pero falla para cero, la cadena vacía y false. ¿Operador existencial de CoffeeScript? devuelve true a menos que una variable sea nula o indefinida, lo que la hace análoga a Ruby's nil?

También se puede utilizar para una asignación condicional más segura que || = , para casos en los que puede manejar números o cadenas.

12

Yo personalmente uso or= en lugar de ?= principalmente porque eso es lo que llamo ||= (o igual) cuando lo uso en Ruby.

robot.brain.data.contacts or= {} 

La diferencia es que or= cortocircuitos cuando robot.brain.data.contacts no es null, mientras que ?= pruebas para null y sólo establece robot.brain.data.contacts a {} si no null.

See the compiled difference.

Como se ha mencionado en otro post, ni método comprueba la existencia de robot, robot.brain o robot.brain.data, pero tampoco lo hace el equivalente Ruby.

Editar:

Además, en CoffeeScript or= y ||= compilación para el mismo JS.

+1

'o = ' y '? =' no se compila en el mismo JS. '? =' realiza una comprobación nula. Ver [esto] (http://coffeescript.org/#try:a%20%3D%20b%20%3D%200%0A%0Aa%20or%3D%201%3B%0Ab%20%3F%3D% 201% 3B) para la diferencia cuando se usan diferentes nombres de variables. –

1

El dialecto Coco de CoffeeScript, http://github.com/satyr/coco, es compatible con los operadores autovivification objeto y matriz @ y @@:

[email protected]@[email protected] = 1 

compila a - sentado, peluda de aspecto -

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

que garantiza que cada paso del camino, robot.brain, brain.data, data.contacts realmente existe.

Por supuesto, es posible que quieran el operador real condicional de asignación (que, de acuerdo con las respuestas anteriores, también existe en CoffeeScript):

robot.brain.data.contacts ?= {} 

que compila a

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