MODULARIDADE


  Foi visto até aqui que variáveis globais e funções (ou procedimentos) do Pascal e C não podem ter nomes repetidos. Isto é um problema, pois limita a capacidade de criação de nomes de funções e variáveis. Além disso, ao se criar nomes diferenciados de funções como, por exemplo, calcula2() para diferenciar de calcula(), pode-se gerar uma certa confusão, visto que não fica claro a que contexto pertence cada função.
  Para resolver esse problema, as linguagens evoluiram e criaram o conceito de modularidade. Assim, tornou-se possível agregar funções por assunto e ao mesmo tempo isolá-las do programa principal. O acesso a tais funções ou variáveis é geralmente realizado mediante ao acréscimo do nome do módulo, solucionando-se o problema de repetição de nomes.
  As principais vantagens da modularidade são:   Infelizmente os compiladores do MSX não dão suporte a esses recursos, uma vez que são versões mais antigas dessas linguagens. O máximo que conseguimos até aqui foi o agrupamento e o reuso por parte do recurso de "include files", persistindo ainda o problema do isolamento e distinção de nomes. Entretanto, é possível simular a modularidade no MSX.
  Dessa forma, primeiramente serão introduzidos esses novos conceitos e depois uma maneira de simulá-los.



  O namespace do C

  O namespace do C é a forma mais simples de modularidade. Permite somente o isolamento de funções e variáveis.
  O exemplo a seguir cria um módulo chamado "area", onde as funções e variáveis estarão isoladas do programa principal. O acesso a eles é feito através do nome do namespace, seguido de dois sinais de dois pontos (area::).
#include <stdio.h>

namespace area { int a = 5; int retorna_valor() { return 10; } };
int a = 3; int retorna_valor() { return 6; } int main(void) { printf("Valor da variavel do namespace: %d\n", area::a); printf("Valor da funcao do namespace: %d\n", area::retorna_valor()); printf("Valor da variavel: %d\n", a); printf("Valor da funcao: %d\n", retorna_valor()); return 1; }
  Saída:
Valor da variavel do namespace: 5
Valor da funcao do namespace: 10
Valor da variavel: 3
Valor da funcao: 6

  Observe no exemplo a seguir, como podemos diferenciar duas funções com o mesmo nome "calcula": uma para o módulo de matemática e outra para o módulo de física.
#include <stdio.h>

namespace mat { double calcula(double a, double b) { return a * b; } };
namespace fis { double calcula(double ds, double dt) { return ds / dt; } };
int main(void) { printf("Cálculo matemática: %.2f\n", mat::calcula(4, 2)); printf("Cálculo física: %.2f\n", fis::calcula(4, 2)); return 1; }
  Saída:
Cálculo matemática: 8.00
Cálculo física: 2.00

  Assim, a função mat::calcula(4, 2) fez acesso ao módulo de matemática, enquanto que fis::calcula(4, 2) fez acesso ao módulo de física.




  O unit do Pascal

  O unit do Pascal oferece algumas outras funcionalidades além do isolamento. São elas: o acesso externo ao módulo de modo público e privado e funções de inicialização e encerramento do módulo.
  O acesso público permite que o programa principal ou outros módulos acessem funções ou variáveis do módulo em questão. Entretanto, o acesso privado permite que somente o módulo que possua a variável ou função tenha acesso a eles, proibindo o acesso aos demais.
  A função de inicialização é posta em execução automaticamente sempre que o unit é carregado, enquanto que a função de encerramento é posta em execução sempre que o programa termima.
  Enquanto que o namespace do C pode vir no mesmo arquivo ou não do programa principal, cada unit do Pascal deverá ser gravado em um arquivo separado. O unit é chamado através do comando "uses", seguido do nome do arquivo, que deverá ter o mesmo nome do unit.

  Sintaxe do unit:
unit nome_do_unit;

interface 
{ código público }

implementation 
{ código privado }

end.
  Agora, vamos repetir os módulos de matemática e física apresentados no namespace do C:

arquivo: mat.pas
unit mat;

interface {public}

function calcula(a, b : double) : double;


implementation {private}

function calcula(a, b : double) : double;
begin
  calcula := a * b;
end;

end.

arquivo: fis.pas
unit fis;

interface {public}

function calcula(ds, dt : double) : double;


implementation {private}

function calcula(ds, dt : double) : double;
begin
  calcula := ds / dt;
end;

end.

arquivo principal: main.pas
uses mat, fis;

begin
  writeln('Calculo matematica: ', mat.calcula(4,2));
  writeln('Calculo fisica: ', fis.calcula(4,2));
end.
  Saída:
Calculo matematica: 8.0
Calculo fisica: 2.0



  Simulando modularidade no MSX

  Como dito anteriormente, o MSX não dispõe dos recursos de modularidade. Então, como simulá-los?
  A resposta é simples. Basta adicionar um prefixo às funções ou variáveis com o nome do "módulo".
  Um exemplo prático disso é o que faz o programa "gbasic.bin", que tem como por objetivo adicionar novos comandos em Basic para se ter acesso aos recursos do VDP V9990 do MSX. O programa acrescenta a letra "G" aos novos comandos do Basic, para diferenciá-los dos comandos originais, como, por exemplo, GSCREEN para diferenciar de SCREEN, GCLS de CLS, GCOLOR de COLOR etc.
  Assim, os módulos de física e matemática poderiam ser reescritos da seguinte maneira:

arquivo: mat.pas
function mat_calcula(a, b : double) : double;
begin
  mat_calcula := a * b;
end;

arquivo: fis.pas
function fis_calcula(ds, dt : double) : double;
begin
  fis_calcula := ds / dt;
end;

arquivo principal: main.pas
{$i mat.pas}
{$i fis.pas}

begin
  writeln('Calculo matematica: ', mat_calcula(4,2));
  writeln('Calculo fisica: ', fis_calcula(4,2));
end.
  Saída:
Calculo matematica: 8.0
Calculo fisica: 2.0


/MARMSX/CURSOS/PASCAL