terça-feira, 19 de outubro de 2010

IIF

Quem já programou em Clipper e Visual Fox Pro deve lembrar da função IIF. Esta função simplesmente aceitava três parâmetros, um booleano, ou condição, e dois valores, caso verdadeiro e caso falso.
Ela era interessante porque substituia (em partes) o operador ternário ?: do C e poderia ser usada em expressões para se somar ou concatenar o valor correto dependendo da condição.
Ela servia para substituir um if ... else e uma variável temporária colocando tudo na mesma linha.

O seu formato era:

iif(condição, valor se verdadeiro, valor se falso): valor;

Ela retornava um valor que seria do mesmo tipo do segundo e terceiro argumento.

É possível criar inúmeras variantes dessa função, tanto no Lazarus como no Delphi. Usando variants poderiamos  criar uma vertente da função que funcionaria para qualquer tipo de dado primitivo.

Mas o Delphi é ainda mais flexível porque hoje temos Generics e o tipo TValue, que são mais flexíveis ainda. Com Generics, Variants e sobrecarga de operadores podemos utilizar sim qualquer tipo de valor, classes, objetos instanciados e assim por diante. Além disso, com expressões lambda e funções "inline" podemos inclusive colocar função/execução de código no IIF o que extrapola o seu objetivo de substituir o operador ternário. Ele se torna realmente um if...else. Esse tipo de coisa poderíamos fazer nas versões antigas do Delphi e no Lazarus apenas com ponteiros para métodos.

Esse código abaixo mostra um exemplo da função IIF e seu uso, inclusive com generics nas versões modernas do Delphi.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: T): T;

implementation

{$R *.dfm}

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: T): T; 
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;

function iif(condicao: Boolean; ValorVerdadeiro, ValorFalso: string): string;
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  a,b, resultado: string;
  x,y: integer;
  debita: boolean;
begin

  a := 'Clube';
  b := 'Delphi';

  x := 1;
  y := 2;

  debita := true;
  resultado:= inttostr(iif(debita, y-1, y+1));
  ShowMessage(resultado);

  debita := false;
  resultado:= inttostr(iif(debita, y-1, y+1));
  ShowMessage(resultado);

  resultado:= iif(x=y, 'x é igual a y', 'x é diferente de y');
  ShowMessage(resultado);

  x := y;
  resultado:= iif(x=y, 'x é igual a y', 'x é diferente de y');
  ShowMessage(resultado);

  resultado:= iif((a<>'')and (b<>''), a + ' ' + b , 'um dos dois é vazio');
  ShowMessage(resultado);

  a := '';
  resultado:= iif((a<>'')and (b<>''), a + ' ' + b , 'um dos dois é vazio');
  ShowMessage(resultado);

  resultado:= iif(a=b, 'a e b são iguais', 'a e b são diferentes');
  ShowMessage(resultado);

end;

end.



Aqui criamos apenas duas versões, uma com generics (que funcionará para tudo) e uma com strings. Poderíamos criar com variants ou qualquer outra coisa.

Uma alteração interessante que pode ser feita também é declarar os argumentos/parâmetros das funções como const, assim eles não poderão ser temporariamente modificados por expressões lambda ou código dentro do corpo de IIF.


function iif(const condicao: Boolean; const ValorVerdadeiro, ValorFalso: T): T;

{...}

function iif(const condicao: Boolean; const ValorVerdadeiro, ValorFalso: T): T; 
begin
  if condicao then
    Result := ValorVerdadeiro
  else
    Result := ValorFalso;
end;


Espero que seja útil para todos. Pelo menos saudosista é ;)

Nenhum comentário:

Postar um comentário

Postagens populares

Marcadores

delphi (60) C# (31) poo (21) Lazarus (19) Site aos Pedaços (15) sql (13) Reflexões (10) .Net (9) Humor (9) javascript (9) ASp.Net (8) api (8) Básico (6) Programação (6) ms sql server (5) Web (4) banco de dados (4) HTML (3) PHP (3) Python (3) design patterns (3) jQuery (3) livros (3) metaprogramação (3) Ajax (2) Debug (2) Dicas Básicas Windows (2) Pascal (2) games (2) linguagem (2) música (2) singleton (2) tecnologia (2) Anime (1) Api do Windows (1) Assembly (1) Eventos (1) Experts (1) GNU (1) Inglês (1) JSON (1) SO (1) datas (1) developers (1) dicas (1) easter egg (1) firebird (1) interfaces (1) introspecção (1) memo (1) oracle (1) reflexão (1)