jueves, 8 de enero de 2009

El Meta Modelo

Meta Modelo
En un ambiente de objetos todo es un objeto, cadenas, números reales, números enteros, código fuente (instancias de CompiledMethod), clases y metaclases.

Como funciona el Meta Modelo en Smalltalk

Cuando creo una clase digamos Alfil (para simular un juego de ajedrez) se crean dos cosas:
1. La meta clase Alfil class
2. La clase Alfil

Alfil class y Alfil son dos cosas diferentes. Alfil class es la meta clase de la clase Alfil.
(o con el clásico ejemplo: Cliente class y Cliente)
La única instancia de Alfil class es Alfil. Es decir, que cada meta clase (en este ejemplo la meta clase Alfil classtiene un única instancia (es un como un singleton), y esta instancia es la clase Alfil. Y las instancias de la clase Alfil son los alfiles que utilizo en la partida.

REGLAS
1. "Cada clase es instancia de su meta clase"
2. "Cada meta clase es instancia de la clase Metaclass"

Por cada clase que creo en mi modelo, Cliente, Factura, IVA, etc voy a tener la correspondiente meta clase: nombre de la clase + class.

Ahora bien, si todo es un objeto, que clase de objeto es una meta clase ?
Cada meta clase (Alfil class) es una instancia de la clase Metaclass (observar que es Metaclass solamente, sin el post fijo class), es decir, Metaclass es una clase.

Resumiendo tenemos que:
Mi clase Alfil es una instancia de Alfil class (que se crea cuando creo Alfil).
Además Alfil class es una instancia de Metaclass.

Esto nos lleva a una aparente "contradicción", que es interesante.

Por regla 1 entonces tendría que Metaclass es instancia de su meta clase pero por regla 2 cada meta clase es instancia de Metaclass.

El Meta Modelo de Smalltalk se apoya en esta aparente contradicción dónde Metaclass es instancia de Metaclass class (regla 1), y que Metaclass class es instancia de Metaclass (regla 2). Metaclass es una instancia de si misma, es casi filosófico (esto en broma claro, jajaja)

La jerarquía de clases es la siguiente:
Behavior
ClassDescription
Class
Metaclass

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.