A linguagem
Regiões, forward e initialization
Organizar um módulo com public region, esconder o resto, declarar rotinas adiantadas e a ordem de initialization e finalization.
O que é e por que existe#
Um módulo .fxm não tem interface/implementation: cada declaração diz se é public (visível a quem usa o módulo) ou private (a omissão). Escrever public em cada item cansa; a região agrupa vários e os torna públicos de uma vez. E para recursão mútua entre rotinas, forward declara só o cabeçalho.
module Parity;
var GCalls: Int32; // sem marca: private
private function IsOdd(N: Int32): Bool8; forward; // só o cabeçalho
public region 'Parity.Public'; // tudo daqui até "end region" é público
type
TParityReport = record
Value: Int32;
Parity: UString;
end record;
function IsEven(N: Int32): Bool8;
begin
Inc(GCalls);
if N = 0 then Exit(True);
Exit(IsOdd(N - 1));
end function;
end region;
function IsOdd(N: Int32): Bool8; // fora da região: continua private
begin
Inc(GCalls);
if N = 0 then Exit(False);
Exit(IsEven(N - 1));
end function;public region 'rótulo'; … end region;: o rótulo serve à IDE. Fora de região, escrevapublicem cada item.forward: declara o cabeçalho; o corpo vem depois. Permite recursão mútua (IsEveneIsOdd).- O programa só enxerga o que o módulo declarou público: citar
GCallsouIsOddno programa seria erro de compilação.
initialization e finalization#
initialization roda uma vez, quando o programa inicia (antes do begin principal); finalization roda ao encerrar, em ordem inversa à da inicialização. A ordem das mensagens no demo mostra isso:
program Regions;
// Demo: organização de módulos. Veja Parity.fxm: `public region`, `private`, `forward`,
// `initialization` e `finalization`. O programa só enxerga o que o módulo declarou público.
uses System.Remainder, Parity;
var
LReport: TParityReport;
begin
WriteLn('[Regions] início do programa');
LReport := Describe(7);
WriteLn(LReport.Value, ' é ', LReport.Parity);
WriteLn('10 é par? ', IsEven(10));
WriteLn('chamadas feitas dentro do módulo: ', CallCount);
// GCalls e IsOdd são private em Parity: citá-los aqui seria erro de compilação
WriteLn('[Regions] fim do programa');
end.module Parity;
// Demo de organização de um módulo: `public region`, `private`, `forward`, initialization/finalization.
uses System.Remainder;
var
GCalls: Int32; // sem marca: a omissão num módulo é private (invisível fora daqui)
// `forward` declara só o cabeçalho; o corpo vem depois. Permite recursão mútua (IsEven <-> IsOdd).
private function IsOdd(N: Int32): Bool8; forward;
// `public region 'rótulo'; ... end region;` agrupa declarações e torna PÚBLICO tudo que está dentro
// (o rótulo é para a IDE). Fora de região, é preciso escrever `public` em cada item.
public region 'Parity.Public';
type
TParityReport = record
Value: Int32;
Parity: UString;
end record;
function IsEven(N: Int32): Bool8;
begin
Inc(GCalls);
if N = 0 then
Exit(True);
Exit(IsOdd(N - 1));
end function;
function Describe(N: Int32): TParityReport;
begin
Result.Value := N;
if IsEven(N) then
Result.Parity := 'par'
else
Result.Parity := 'ímpar';
end function;
function CallCount: Int32;
begin
Exit(GCalls);
end function;
end region;
// fora da região: continua private, mas fecha a recursão mútua iniciada pelo forward
function IsOdd(N: Int32): Bool8;
begin
Inc(GCalls);
if N = 0 then
Exit(False);
Exit(IsEven(N - 1));
end function;
// roda uma vez, quando o programa inicia (antes do begin principal)
initialization
GCalls := 0;
WriteLn('[Parity] inicializado');
// roda ao encerrar, em ordem inversa à da inicialização
finalization
WriteLn('[Parity] finalizado após ', GCalls, ' chamadas');
end.[Parity] inicializado
[Regions] início do programa
7 é ímpar
10 é par? TRUE
chamadas feitas dentro do módulo: 19
[Regions] fim do programa
[Parity] finalizado após 19 chamadasDemo 54. [Parity] inicializado, depois o programa, depois [Parity] finalizado com a contagem de chamadas.
Armadilhas#
- O corpo da rotina
forwardvem depois, no mesmo módulo; sem ele o compilador acusa "declarado mas não implementado" (FE0960). Se a intenção é só declarar, useexternal,forwardouabstract. - A região só torna públicos os itens declarados dentro dela; os que ficam depois do
end regionvoltam a ser privados. - Em módulo em ciclo, a ordem das
initializationé a da conclusão da leitura (veja Módulos que se citam).
Veja também#
- Módulos e visibilidade (inclui
protected,rad_region). - Demo
54-regioes-forward.