martes, 6 de enero de 2009

La "sentencia" IF es un Mensaje (no una sentencia) a un objeto booleano

La sentencia IF es un Mensaje a un objeto booleano

Al trabajar en un ambiente de objetos todo es un mensaje a un objeto, la "sentencia" if tambien !!
En Smalltalk para indicar la toma de decisión frente a un objeto booleano se hace de la siguiente forma:
Cliente
saldoSupera: anInteger desplegar: mensajeString
"Si el saldo del receptor del mensaje supera <anIntegerentonces desplega el mensaje <mensajeString>"

self saldo anInteger ifTrue:[MessageBox notifymensajeString]

En este caso sencillo vemos como IF es un mensaje, a quien? como funciona?

self saldo - retorna un número y este se compara con anInteger, o sea, si:
self saldo = 450 y anInteger=300
450>300 devuelve un objeto Booleano en este caso True.
Boolean (jerarquia de clases)
False
True
El mensaje es ifTrue: y se le pasa como parametro: [MessageBox notify: mensajeString].
En Smalltalk cualquier secuencia de mensajes puesta entre [parentesis rectos] es una instancia de la clase BlockClosure (el nombre de esta clase puede diferir según el Smalltalk). Si le envio el mensaje value entonces el BlockClosure envia todos los mensajes contenidos en él.
Ejemplos de uso de BlockClosure:

block := [MessageBox notify: 'Hola Mundo'.  MessageBox notify: 'Hola Mundo otra vez'.].
"Despues de evaluar la expresion anterior la variable block ahora es una instancia de BlockClosure. "
block value. "me muestra los mensajes Hola Mundo y luego Hola Mundo otra vez"

tablaDelTres := [:numero | numero * 3].
"Este es un BlockClosure con parametro"
tablaDelTres value: 3. "devuelve 9"
tablaDelTres value: 6. "devuelve 18"
tablaDelTres value: 11. "devuelve 33" 

Estos son ejemplos muy sencillos de como se utilizan los BlockClosure en Smalltalk. A nivel de aplicaciones comerciales se utilizan para indicar que se hace en caso de alguna Excepcion. En Smalltalk los bloques de código se pueden pasar como parametros. En otra ocasión publicaré sobre los BlockClosure en Smalltalk, ya que casi no tienen igual en la programación, y los ejemplos aqui expuestos son bastantes sencillos.

Por lo que los BlockClosure se utilizan para la famosa sentencia IF.
Las clases True y False implementan los 4 mensajes:
#ifTrue:
#ifFalse:
#ifTrue:ifFalse:
#ifFalse:ifTrue:
Ahora veremos como cada clase implementa cada uno de estos mensajes:
True
ifTrue: aBlockClosure
"Evaluate and answer the result of the evaluating the
argument, aBlockClosure, if the receiver is true, otherwise answer nil. "
^aBlockClosure value

ifFalseaBlockClosure
"Evaluate and answer the result of the evaluating the
argument, aBlockClosure, if the receiver is false, otherwise answer nil."
^nil

ifTrue: trueBlock ifFalse: falseBlock
"Evaluate, and answer the result, of the , falseBlock, if 
the receiver is false, or the , trueBlock , if the receiver is 
true."
^trueBlock value

ifFalse: falseBlock ifTruetrueBlock 
"Evaluate, and answer the result, of the , falseBlock , if the receiver is false, or the , trueBlock , if the receiver is true."
^trueBlock value

False
ifTrueaBlockClosure
"Evaluate and answer the result of the evaluating the
argument, aBlockClosure, if the receiver is true, otherwise answer nil."
^nil

ifFalseaBlockClosure
"Evaluate and answer the result of the evaluating the
argument, aBlockClosure, if the receiver is false, otherwise answer nil. "
^aBlockClosure value

ifTrue: trueBlock ifFalsefalseBlock
"Evaluate, and answer the result, of the , falseBlock , if the receiver is false, or the , trueBlock , if the receiver is true."
^falseBlock value

ifFalse: falseBlock ifTruetrueBlock 
"Evaluate, and answer the result, of the , falseBlock , if the receiver is false, or the , trueBlock , if the receiver is true."
^falseBlock value

(4 > 5) ifTrue:[some code]. 
"4> 5 retorna el objeto false, entonces queda: false ifTrue:[some code].
Si vamos a la implementacion de ifTrue: de False vemos que retorna nil, entonces [some code] no es evaluado "
(4 > 5) ifFalse:[some code]. 
"4> 5 retorna el objeto falseentonces queda: false ifFalse:[some code].
Si vamos a la implementacion de ifFalsede False vemos que retorna ^aBlock value , entonces [some code] es evaluado "
De la misma forma funciona para el resto de los mensajes de Boolean.

La sentencia if en Smalltalk esconde la magia de los BlockClosures, que en Smalltalk se utilizan ampliamente.

No hay comentarios: