2010-06-27 5 views
7
a > b 
ifTrue:[ 'greater' ] 
ifFalse:[ 'less or equal' ] 

Mi entendimiento es que Boole a> b recibe el ifTrue mensaje: [ 'mayor'], y luego ifFalse: [ 'menor o igual'] cumplimiento a la generalización:Por qué if True e ifFalse no están separados por; en Smalltalk?

objectInstance selector; selector2 

Pero hay una Se necesita un punto y coma para especificar que el receptor de selector2 no es (selector de instancia de objeto) sino objectInstance. ¿No es lo mismo con la ejecución condicional anterior?

+0

Solo por completitud, el; es para una _cascada_ - una secuencia de mensajes enviados al mismo objeto. foo bar; baz. es idéntico en significado a foo bar. foo baz. –

+0

su comprensión es incorrecta; no es "recibe ... Y LUEGO ...", sino "recibe un mensaje". Ver mi respuesta a continuación. – blabla999

Respuesta

19

El selector del método es Boolean>>ifTrue:ifFalse:, lo que significa que es el método uno con dos parámetros, no dos métodos con uno parámetro.

Ergo, para invocar el método, le envía el mensaje ifTrue:ifFalse: con dos argumentos de bloque.

Tenga en cuenta que por razones de conveniencia, también hay métodos Boolean>>ifFalse:ifTrue:, Boolean>>ifTrue: y Boolean>>ifFalse:.

7

todo lo relevante ya se ha Sayd, pero sólo para su diversión:

Como ya se ha dicho,

rcvr ifTrue:[...] ifFalse:[...] 

es el único y solo mensaje # 'ifTrue: ifFalse:' con 2 args enviado a rcvr. El valor de esa expresión es el de ese mensaje enviado. En contraste:

rcvr ifTrue:[...]; ifFalse:[...] 

es una cascada de 2 mensajes secuenciales (# 'ifTrue: 'y #' ifFalse:'), cada uno con 1 arg enviado a RCVR. El valor de la expresión es el devuelto desde el último envío.

Ahora lo curioso es que booleanos entienden ifTrue:/ifFalse: (cada uno con 1 arg), lo que el código funciona para el efecto secundario (evaluación de esos bloques), pero no por su valor. Esto significa que:

a > b ifTrue:[Transcript showCR:'gt'] ; ifFalse:[Transcript showCR:'le'] 

genera la misma salida que:

a > b ifTrue:[Transcript showCR:'gt'] ifFalse:[Transcript showCR:'le'] 

pero:

msg := a > b ifTrue:['gt'] ; ifFalse:['le'] 

generará valores diferentes en msg que:

msg := a > b ifTrue:['gt'] ifFalse:['le'] 

según los valores de a y b. Pruebe (a b) = (1 2) vs. (a b) = (2 1) ...

El problema de muchos principiantes Smalltalk es que piensan en ifXXX: como sintaxis, donde en realidad es un mensaje de envío que genera valor. Además, el semi no es un separador de enunciados como en muchos lenguajes aprendidos previamente, sino un constructo de secuencia de envío de mensajes.

Una trampa mala para los principiantes, porque el código parece funcionar para algunas combinaciones de valores particulares, mientras que genera resultados divertidos para los demás. Esperemos que las pruebas unitarias cubren estos ;-)

de edición: para ver donde el valor malo viene, echar un vistazo a lo que se devuelve por el booleana >> ifFalse: método para un verdadero receptor ...

+0

+1 para notificación de diferentes valores devueltos –

Cuestiones relacionadas