Comentamos en el tema 10 que en muchos lenguajes de programación podemos manejar una serie de bibliotecas externas (en ingles, library) de funciones y procedimientos, que nos permitían ampliar el lenguaje base.
En Turbo Pascal, estas bibliotecas reciben el nombre de "unidades"
(unit), y existen a partir de la versión 5. También existen en otras versiones de Pascal recientes, como Free Pascal.
En su momentos, empleamos la unidad CRT, que nos daba una serie de facilidades para manejar la pantalla en modo texto, el teclado y la generación de sonidos sencillos.
Iremos viendo otras unidades estándar cuando accedamos a la pantalla en modo gráfico, a los servicios del sistema operativo, etc. Pero hoy vamos a ver cómo podemos crear las nuestras propias.
¿Para qué? Nos podría bastar con teclear en un programa todas las funciones que nos interesen. Si creamos otro programa que las necesite, pues las copiamos también en ese y ya está, ¿no?
¡ NO ! Las unidades nos ayudan a conseguir dos cosas:
Me explico: imaginemos que estamos haciendo un programa de rotación
de objetos en tres dimensiones. Creamos nuestra biblioteca de funciones,
y la aprovechamos para todos los proyectos que vayamos a hacer en tres
dimensiones. No solo evitamos reescribir en cada programa el procedimento
RotaPunto, p.ej.., que ahora se tomará de nuestra unidad "MiGraf3D", sino que si descubrimos una forma más
rápida de rotarlos, todos los programas que utilicen el procedimiento
RotaPunto se verán beneficiados sólo con recompilarlos.
Pero vamos a lo práctico...
Una "unit" tiene dos partes: una pública, que
es aquella a la que podremos acceder, y una privada, que es el desarrollo
detallado de esa parte pública, y a esta parte no se puede acceder
desde otros programas.
La parte pública se denota con la palabra "interface", y la privada con "implementation".
Debajo de interface basta indicar los nombres de los procedimientos que queremos "exportar", así como las variables, si nos interesase crear alguna. Debajo de implementation escribimos realmente estos procedimientos o funciones, tal como haríamos en un programa normal.
Veamos un ejemplito para que se entienda mejor.
Nota: este ejemplo NO SE PUEDE EJECUTAR. Recordemos que
una Unit es algo auxiliar, una biblioteca de funciones y procedimientos
que nosotros utilizaremos DESDE OTROS PROGRAMAS. Después de
este ejemplo de Unit incluyo un ejemplo de programa cortito que la emplee.
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Unidad que "mejora" }
{ la CRT }
{ MICRT1.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
unit miCrt1;
interface { Parte "pública", que se exporta }
procedure AtXY( X, Y: byte ; texto: string );
{ Escribe un texto en ciertas coordenadas }
implementation { Parte "privada", detallada }
uses crt; { Usa a su vez la unidad CRT }
procedure AtXY( X, Y: byte ; texto: string );
begin
gotoXY( X, Y); { Va a la posición adecuada }
write( texto );
end;
end. { Final de la unidad }
Este ejemplo declara un procedimiento "AtXY" que hace un GotoXY
y un Write en un solo paso.
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Programa que usa la }
{ unit "MICRT1" }
{ PMICRT1.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
program PruebaDeMiCrt1;
uses miCrt1;
begin
AtXY( 7, 5, 'Texto en la posición 7,5.' );
end.
Este programa no necesita llamar a la unidad CRT original, sino que
nuestra unidad ya lo hace por él.
Ahora vamos a mejorar ligeramente nuestra unidad, añadiéndole un procedimiento "pausa":
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Unidad que mejora la }
{ CRT (segunda versión) }
{ MICRT2.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
unit miCrt2; { Unidad que "mejora más" la CRT }
{-------------------}
interface { Parte "pública", que se exporta }
procedure AtXY( X, Y: byte ; texto: string );
procedure Pausa;
{-------------------}
implementation { Parte "privada", detallada }
uses crt; { Usa a su vez la unidad CRT }
var tecla: char; { variable privada: el usuario no
puede utilizarla }
procedure AtXY( X, Y: byte ; texto: string );
begin
gotoXY( X, Y); { Va a la posición adecuada }
write( texto );
end;
procedure Pausa; { Pausa, llamando a ReadKey }
begin
tecla := ReadKey; { El valor de "tecla" se pierde }
end;
{-------------------}
end. { Final de la unidad }
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Prueba de la unidad }
{ MICRT2 }
{ PMICRT2.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
program PruebaDeMiCrt2;
uses crt, miCrt2;
begin
ClrScr; { De Crt }
atXY( 7, 5, 'Texto en la posición 7,5.' ); { de miCrt2 }
pausa; { de miCrt2 }
end.
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Unidad que mejora la }
{ CRT (tercera versión) }
{ MICRT3.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
unit miCrt3; { Unidad que "mejora más" la CRT }
{-------------------}
interface { Parte "pública", que se exporta }
var EraMono: boolean; { Variable pública, el usuario puede
acceder a ella }
procedure AtXY( X, Y: byte ; texto: string );
procedure Pausa;
{-------------------}
implementation { Parte "privada", detallada }
uses crt; { Usa a su vez la unidad CRT }
var tecla: char; { variable privada: el usuario no
puede utilizarla }
procedure AtXY( X, Y: byte ; texto: string );
begin
gotoXY( X, Y); { Va a la posición adecuada }
write( texto );
end;
procedure Pausa; { Pausa, llamando a ReadKey }
begin
tecla := ReadKey; { El valor de "tecla" se pierde }
end;
{-------------------} { Aquí va la inicialización }
begin
if lastmode = 7 { Si el modo de pantalla era monocromo }
then EraMono := true { EraMono será verdadero }
else EraMono := false; { si no => falso }
end. { Final de la unidad }
{--------------------------}
{ Ejemplo en Pascal: }
{ }
{ Prueba de la unidad }
{ MICRT3 }
{ PMICRT3.PAS }
{ }
{ Este fuente procede de }
{ CUPAS, curso de Pascal }
{ por Nacho Cabanes }
{ }
{ Comprobado con: }
{ - Free Pascal 2.2.0w }
{ - Turbo Pascal 7.0 }
{ - Tmt Pascal Lt 1.20 }
{--------------------------}
program PruebaDeMiCrt3;
uses crt, miCrt3;
begin
ClrScr; { De Crt }
atXY( 7, 5, 'Texto en la posición 7,5.' ); { de miCrt3 }
if not EraMono then
atXY ( 10, 10, 'Modo de color ' );
pausa; { de miCrt3 }
end.
Se podría hablar mucho más sobre las unidades, pero intentaré ser breve: