martes, 29 de enero de 2008

Nuevo en Delphi #2: Sobrecarga de operadores

Esta característica, aunque no añade funcionalidad, es simple pero poderosa en la legibilidad del código. La sobrecarga de operadores solo funciona en Records en Delphi win32 y para Records y Classes en Delphi.Net.

La sobrecarga de operadores consiste en poder definir un metodo de clase declarado como class operator, que se ejecuta cuando se utiliza dicho operador con ciertas clases como operandos, es decir que si definimos:

var
TTequila
= record
public
VolumenMiliLitros: integer;
GradoAlcohol: Single;
class operator Add(
TeqA, TeqB: TTequila): TTequila;
class operator GreaterThan(
TeqA, TeqB: TTequila): Boolean;
end;

class operator TTequila.Add(
TeqA, TeqB: TTequila): TTequila;
var
porcentAEnMezcla, porcentBEnMezcla: single;
begin
// Al mezclar (sumar) dos tequilas se obtiene
// la suma de su volumen liquido...
Result.VolumenMiliLitros :=
TeqA.VolumenMiliLitros
+TeqBVolumenMiliLitros;
// ...pero se promediaria su grado de alcohol
// en proporcion al volumen (en teoria)
porcentAEnMezcla :=
TeqA.VolumenMiliLitros
/Result.VolumenMiliLitros;
porcentBEnMezcla :
=
TeqB.VolumenMiliLitros
/Result.VolumenMiliLitros;
Result.GradoAlcohol :
=
(TeqA.GradoAlcohol
* porcentAEnMezcla) +
(TeqB.GradoAlcohol
* porcentBEnMezcla);
end;

class operator TTequila.GreaterThan(
TeqA, TeqB: TTequila): Boolean;
begin
if TeqA.GradoAlcohol > TeqB.GradoDeAlcohol then
Result :
= True
else
Result :
= False;
// Tambien podria ser:
// Result := (
// TeqA.GradoDeAlcohol > TeqB.GradoDeAlcohol);
end;


Entonces cuando tuvieramos algo como esto:


var
Jimador, Cazadores: TTequila;
MezclaChafa: TTequila;

begin
Jimador.VolumenMiliLitros :
= 750;
Jimador.GradoDeAlcohol :
= 30;

Cazadores.VolumenMiliLitros :
= 1000;
Cazadores.GradoDeAlcohol :
= 36;

if Cazadores > Jimador then
begin
MezclaChafa :
= Jimador + Cazadores
end
else
begin
MezclaChafa.VolumenMiliLitros :
= 0;
MezclaChafa.GradoDeAlcohol :
= 0;
end;

WriteLn(
'Mezclado ');
WriteLn(
'Volumen: ',
IntToStr(MezclaChafa.VolumenMiliLitros));
WriteLn(
'Grado De Alcohol: ',
FloatToStr(MezclaChafa.GradoDeAlcohol));
end;


El resultado seria:


Mezclado
Volumen: 1750
Grado De Alcohol: 33.4285


Ya que el operador Mayor Que > (GreaterThan) fue sobrecargado para que cuando se desea saber si un TTequila es mayor que otro TTequila (los dos parámetros del operator son TTequila) entonces devuelve Verdadero si el primer TTequila tiene un GradoAlcohol mayor que el otro.


De igual manera, el operador Adición, o Suma + (Add) fue sobrecargado para que cuando se "suman" dos TTequila, el resultado sea otro TTequila con la suma de los volumenes y el proporcional del grado de alcohol de cada uno según el volumen que aportan.


NOTA IMPORTANTE: Otra relativamente "reciente" característica de Delphi es precisamente que los tipos record pueden tener métodos como las clases, con la diferencia que los record son pasados por valor (una copia de ellos) y las clases por referencia (una copia del apuntador hacia la clase).

lunes, 14 de enero de 2008

Nuevo en Delphi #1: Datos de Clase

Primero, una disculpa por esperar tanto para comenzar con la serie de Lo nuevo en Delphi, esta semana pasada fueron días interesantes en los proyectos y el tiempo fue lo primero que se acaba.

Quiero empezar a mencionar las nuevas características de Delphi, abarcando 2006 y 2007, ya que muchas de estas se iniciaron en Delphi 2006 pero se consolidaron en Delphi 2007. El objetivo es analizarlas, saber que tan útiles podrían ser y en donde aplicarían.

Una de las que mas me llamo la atención de inicio son los datos de clase (o Class Data).

Tener datos de clase consiste en tener variables que existen desde que la clase existe (no por objeto o instancia de la clase). Hasta ahora Delphi contaba solo con Métodos de clase.

Los campos/datos/variables de clase pueden ser accesados por todos los objetos de esa clase y pueden ser declarados con los mismos restrictores de acceso (private, public, protected, etc.) de los datos de objeto.

Estos datos compartidos por todas las instancias de una clase son parte de la sintaxis de muchos otros lenguajes pero mas que nada es una técnica cercana de Programación orientada a objetos (POO). Puede usarse, por ejemplo, para controlar datos variables entre muchos threads de cierta clase o heredadas de la misma clase, semáforos, o conteo de instancias y muchas otras cosas.

Claro que podemos usar variables globales para eso desde siempre. Aun así, esta nueva forma del lenguaje hace el código mas legible y mejora la estructura ya que la variable tiene relación explicita directa con la clase. Al final, la ventajas de esta nueva característica es hacer el código Delphi win32 mas cercano al de Delphi.Net, además de acercarnos a una mejor estructura de POO.

La forma de declarar variables de clase es usando la sección opcional class var en loa declaración de la clase. Un ejemplo podría ser el siguiente:

TCualquierClase = class
private
FiDato: integer;
FsNombre: string;
class var
Control: integer;
//Dato de clase
OtroDato: TStringList; //Otro dato de clase
public
Nombre: string;
...
end;


En este caso, el valor de Control y OtroDato serán datos compartidos por todas las instancias de TCualquierClase mientras que FiDato, FsNombre y Nombre son datos particulares de cada instancia.



En un futuro (yo espero y ruego) mediante esta característica también seria mas fácil y claro implementar soporte multihilo (multithread-safe) en todo el lenguaje y la VCL, así como tiene actualmente Java en su respectiva, pero sin que sea necesario correr los programas dentro de un ambiente "controlado" y restringido como la máquina virtual.

jueves, 3 de enero de 2008

¡¡ Lo nuevo en Delphi 2007 !! ;)

CodeGear ha estado muy ocupado últimamente haciendo un gran hincapié en "las nuevas características de Delphi en Delphi 2007".

La comunidad internacional, y me refiero a Europa, EUA y quienes ya pudieron acceder a Delphi 2006 o 2007, han tenido diversas reacciones a estas características, en algunos casos tratando de englobarlas de dos maneras: Por un lado algunos opinan que "llevan a Delphi al nuevo siglo" o algo así, mientras que otros concluyen que "son características innecesarias que agregaron solo por que otros lenguajes las tienen y muchos las querían ver en Delphi para no sentirse atrasados". Cualquier polémica por mas ligera que sea, genera alguna opinión radical contrastante.

Voy a comentar algunas de esas características aquí en el blog en los siguientes días, sobre todo las adiciones al lenguaje que son las que mas me han llamado la atención, y de esa manera podemos hacernos una opinión mas concreta.