Pular para o conteúdo principal

Free Pascal - Variáveis Procedurais

Depois de um longo tempo afastado do blog, estamos retornando. Iremos iniciar uma série de artigos dedicados às estruturas de dados do Free Pascal. Mas antes de iniciar é necessário uma breve introdução a variáveis procedurais.
Variáveis procedurais ou tipos procedurais são um recurso do Free Pascal que permite armazenar métodos, funções e procedimentos em variáveis. Tais variáveis podem ser normalmente tratadas, passando-as como parâmetros e chamando os métodos quando for necessário.
Para exemplificar o uso deste recurso vejamos como declarar um tipo procedural:

type
  TFuncaoSemParametro = function(): String;
  TFuncaoComParametro = function(x: String): String;

O primeiro exemplo declara um tipo que armazena um função que não recebe argumentos. O segundo exemplo declara um tipo que armazena uma função que recebe parâmetros.
Tipos procedurais também podem ser declarados de mais duas maneiras, como pode ser visto abaixo. O primeiro declara um tipo para armazenar um procedimento e o segundo armazena um método de uma classe:

type
   TProcedimento = procedure;
   TMetodo = procedure of Object;

Prosseguindo então com nosso exemplo, em seguida iremos declarar as funções:

function AloMundo: String;
begin
  Result := 'Alo Mundo';
end;

function AloNovamente(S: String): String;
begin
  Result := 'Alo ' + S;
end;

Essas duas funções serão usadas como argumentos nas chamadas aos dois procedimentos seguintes, que recebem como parâmetros os tipos procedurais declarados.

procedure Primeiro(f: TFuncaoSemParametro);
begin
  WriteLn(f());
end;

procedure Segundo(f: TFuncaoComParametro);
begin
  WriteLn(f('Novamente'));
end;                 

Observe que tanto o procedimento Primeiro, quanto o procedimento Segundo executam a função que recebem como parâmetro. As funções chamadas irão retornar Strings que serão escritas no console através de writeln.
Para testar a funcionalidade apenas chame os procedimentos assim:

Primeiro(@AloMundo);
Segundo(@AloNovamente);

O símbolo @ converte a variável em um ponteiro. É desta forma que a função é passada como parâmetro.
É importante observar que o compilador verifica se a função ou o procedimento que está sendo passado como parâmetro corresponde exatamente ao esperado, ou seja, possui os mesmos parâmetros, o mesmo tipo de retorno, etc.
O mecanismo usado pelos eventos de componentes da biblioteca do Lazarus é exatamente este. Veja como pode ser criado um componente dinamicamente e como atribuir um método a um evento de um TButton no post Lazarus - Criando componentes em run-time.
A seguir o código completo da aplicação console:

program procvar;

{$mode objfpc}{$H+}

uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes
  { you can add units after this };
type
  TFuncaoSemParametro = function(): String;
  TFuncaoComParametro = function(x: String): String;

function AloMundo: String;
begin
  Result := 'Alo Mundo';
end;

function AloNovamente(S: String): String;
begin
  Result := 'Alo ' + S;
end;

procedure Primeiro(f: TFuncaoSemParametro);
begin
  WriteLn(f());
end;

procedure Segundo(f: TFuncaoComParametro);
begin
  WriteLn(f('Novamente'));
end;

{$R *.res}

begin
  Primeiro(@AloMundo);
  Segundo(@AloNovamente);
  ReadLn;
end.

Atualizado em 03/05/2011.

Comentários

Unknown disse…
Olá Professor, estou criando uma aplicação em Lazarus e encontrei esse excelente blog sobre o mesmo e o estou seguindo, porém, estou tendo uma dúvida sobre formulários, é o seguinte: no form principal tem um menu com botões e um dos botões chama um outro formulário e dentro deste formulário(2) tem um botão fechar.Como faço quando clicar nesse botão fechar(que fecha o segundo formulário) e chamar o formulário principal?
Agradeço a atenção do Senhor e parabéns pelo blog.
Professor Carlos disse…
Gustavo

No primeiro botão você chama o segundo form usando o método show() ou showmodal(). O principal continua aberto, mas talvez oculto pelo seu segundo form. No segundo form, chame o método close() no botão fechar e pronto.

Postagens mais visitadas deste blog

Lazarus - Acessando banco de dados com SQLdb - Parte I

Para fazer nossa primeira aplicação usando banco de dados no Lazarus vamos usar o SQLite e o conjunto de componentes nativo SQLdb. Inicialmente vamos apresentar passo como essa aplicação foi criada. Essa foi a maneira que eu fiz, e eu agradeço sugestões e questionamentos que pessoas que já passaram por essa experiência. Depois irei fazer algumas considerações sobre o uso do SQLdb. SQLite SQLite é uma biblioteca que implementa um motor de banco de dados SQL. É livre para qualquer finalidade, seja uso particular ou comercial. Lê e escreve em um único arquivo que pode ter além de tabelas, índices, gatilhos e visões. Executa em várias plataformas e é indicado para aplicações embarcadas. Maiores detalhes podem ser encontrados no site oficial. Para usá-lo, baixe-o do site e faça a instalação adequada para o seu sistema operacional. No Windows isso é muito simples, apenas copie sqlite3.dll para o system32 da pasta do sistema operacional. Existe uma ferramenta de linha de comando chamada

Tipos de dados no SQLite

Em SQLite, diferente de outros motores de banco de dados, o tipo de dado de um valor está associado com o valor propriamente dito, e não com o seu contêiner. É um sistema de tipo dinâmico. Um campo de uma tabela em SQLite pode receber qualquer tipo de dado. Assim, o SQLite simplesmente ignora o tipo informado no comando CREATE TABLE. Então, dizemos que no SQLite existem classes de armazenamento. E essas classes são: NULL - como em qualquer outro banco de dados. INTEGER - inteiro com sinal, armazenado em 1, 2, 3, 4, 6 ou 8 bytes dependendo da grandeza do valor. REAL - valor de ponto flutuante armazenado em 8 bytes. TEXT - uma string armazenada usando UTF-8, UTF-16BE ou UTF-16LE. BLOB - armazena um blob, como indica o nome. Uma coluna INTEGER PRIMARY é uma exceção. Só aceita números inteiros. Qualquer valor em um comando SQL tem uma classe de armazenamento implícita. Durante a execução do comando SQL, o SQLite pode converter valores entre classes numéricas (INTEGER e REAL)

Lazarus - Criando relatórios com FortesReport (Parte I)

Para a criação de relatórios, o Lazarus já trás o componente LazReport, no entanto ele precisa ser instalado no IDE. Para fazer a instalação do pacote, acesse o menu Package -> Open package file (.lpk) . Localize o diretório de instalação do Lazarus e na pasta components abra lazreport e depois source . Abra o pacote lazreport.lpk , clique em Compile e depois em Install . Como já sabemos isso irá recompilar o IDE. Depois de inicializado novamente estará disponível a aba LazReport . Leia aqui um tutorial básico sobre o LazReport. No entanto queremos mostrar uma alternativa ao LazReport . Por essa razão, vamos apresentar neste artigo o FortesReport . Para quem conhece o QuickReport, que fazia parte do Delphi, não terá dificuldade de desenvolver com esse componente. Baixe o pacote aqui e instale. Os procedimentos são semelhantes aos que mostramos acima. Você terá uma nova aba chamada Fortes Report . Conectando o banco de dados O primeiro passo para criar a aplicação é fazer