Fórum (Operador ternário) para procedures/functions #620870
20/12/2023
0
Estou praticando um pouco a programação com Delphi, e queria fazer uma espécie de "Operador ternário" para procedures/functions para não ficar usando If e Else.
A ideia era:
-> OperadorTernario(booleano, procedure, function); ou OperadorTernario(booleano, function, procedure);
tanto para: function - function, procedure - procedure, ect....
Agradeço antecipadamente por qualquer orientação ou sugestão que possam oferecer.
o código que criei por enquanto é bem limitado, pois está dividido em duas funções: uma para operações envolvendo procedures e outra para operações com funções ( as funções devem ter o mesmo tipo de retorno).. Estou em busca de orientações e sugestões para otimizar e unificar essas operações ternárias, possibilitando a execução tanto de procedimentos quanto de funções, independentemente do tipo de retorno.
Obrigado!
Código atual para testes:
https://drive.google.com/drive/folders/1GabYXu4WEgLT-sK87kHVqo9ZWtAEFj6g?usp=sharing
A ideia era:
-> OperadorTernario(booleano, procedure, function); ou OperadorTernario(booleano, function, procedure);
tanto para: function - function, procedure - procedure, ect....
Agradeço antecipadamente por qualquer orientação ou sugestão que possam oferecer.
o código que criei por enquanto é bem limitado, pois está dividido em duas funções: uma para operações envolvendo procedures e outra para operações com funções ( as funções devem ter o mesmo tipo de retorno).. Estou em busca de orientações e sugestões para otimizar e unificar essas operações ternárias, possibilitando a execução tanto de procedimentos quanto de funções, independentemente do tipo de retorno.
Obrigado!
Código atual para testes:
https://drive.google.com/drive/folders/1GabYXu4WEgLT-sK87kHVqo9ZWtAEFj6g?usp=sharing
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | unit OperTernario; interface uses Winapi . Windows, Winapi . Messages, System . SysUtils, System . Variants, System . Classes, Vcl . Graphics, Vcl . Controls, Vcl . Forms, Vcl . Dialogs, Vcl . ExtCtrls, Vcl . StdCtrls; type TProcReference = reference to procedure ; TProcEvent = procedure (Sender: TObject) of object ; TMethodReference = reference to procedure (Sender: TObject); TFuncReference<T> = reference to function : T; type TForm1 = class (TForm) Panel1: TPanel; Button3: TButton; Label1: TLabel; Button1: TButton; procedure Panel1Click(Sender: TObject); procedure Button3Click(Sender: TObject); procedure Button1Click(Sender: TObject); private function WrapEventMethod( const Method: TProcReference): TMethodReference; function WrapEventMethodEvent( const Method: TProcEvent): TMethodReference; function OperTernario(AValue: Boolean ; const ATrue, AFalse: TMethodReference): Boolean ; overload; function OperTernarioFunc<T>(AValue: Boolean ; const ATrue, AFalse: TFuncReference<T>): T; overload; procedure procTrue; procedure procFalse; function funcTrue: Integer ; function funcFalse: Integer ; public { Public declarations } booleano: Boolean ; end ; var Form1: TForm1; implementation {$R *.dfm} function TForm1 . OperTernario(AValue: Boolean ; const ATrue, AFalse: TMethodReference): Boolean ; begin if AValue then ATrue(Self) else AFalse(Self); Result := AValue; end ; function TForm1 . OperTernarioFunc<T>(AValue: Boolean ; const ATrue, AFalse: TFuncReference<T>): T; begin if AValue then Result := ATrue() else Result := AFalse(); end ; function TForm1 . WrapEventMethod( const Method: TProcReference): TMethodReference; begin Result := procedure (Sender: TObject) begin Method(); end ; end ; function TForm1 . WrapEventMethodEvent( const Method: TProcEvent): TMethodReference; begin Result := procedure (Sender: TObject) begin Method(Sender); end ; end ; function TForm1 . funcTrue: Integer ; begin ShowMessage( '' '' '' '' Function True '' '' '' '' ); Result := 0 ; end ; function TForm1 . funcFalse: Integer ; begin ShowMessage( '' '' '' '' Function False '' '' '' '' ); Result := 0 ; end ; procedure TForm1 . procFalse; begin ShowMessage( '' '' '' '' False '' '' '' '' ); end ; procedure TForm1 . procTrue; begin ShowMessage( '' '' '' '' True '' '' '' '' ); end ; procedure TForm1 . Button1Click(Sender: TObject); begin ShowMessage( '' '' '' '' Procedure de Objeto '' '' '' '' ); end ; procedure TForm1 . Button3Click(Sender: TObject); begin booleano := not booleano; Label1 . Caption := BoolToStr(booleano, True ); end ; procedure TForm1 . Panel1Click(Sender: TObject); begin // (procedure) -> (procedure) OperTernario(booleano, WrapEventMethod(procTrue), WrapEventMethod(procFalse)); // (função) -> (função) (Deve ter o mesmo tipo de retorno) OperTernarioFunc< Integer >(booleano, funcTrue, funcFalse); // (procedure) - (procedure de objeto) OperTernario(booleano, WrapEventMethod(procTrue), WrapEventMethodEvent(Button1Click)); end ; end . |

Guilherme Lima
Curtir tópico
+ 0
Responder
Posts
20/12/2023
Arthur Heinrich
Esse tipo de funcionalidade é mais viável em linguagens interpretadas, onde o código é executado dinamicamente.
No caso do Delphi, o compilador precisa decidir o código em tempo de compilação e é importante que a "API", a interface da rotina seja semelhante, para que isto seja possível.
Isto elimina a possibilidade de misturar procedures e functions, ou mesmo de utilizar procedures e functions com diferenças nos parâmetros e tipos de retorno.
A orientação a objetos veio para resolver problemas semelhantes a esse, onde a classe pode ter métodos virtuais, de forma que ao instanciar a classe com um descendente da classe base, ao chamar o método, chamará a função correspondente. Mas, não é o que você pretende fazer.
No seu caso, a ideia é simplificar o código:
if <condição> then <método 1> else <método 2>;
Para:
Operador(<condição>, <método 1>, <método 2>);
Se pararmos para pensar, isso nem economiza nada. O if/then/else continua sendo necessário, mas interno à function/procedure, e seu código precisa executar mais uma chamada de procedure.
Dadas as limitações e o fato de que isto não simplifica tanto o código, eu não utilizaria esse tipo de recurso.
No caso do Delphi, o compilador precisa decidir o código em tempo de compilação e é importante que a "API", a interface da rotina seja semelhante, para que isto seja possível.
Isto elimina a possibilidade de misturar procedures e functions, ou mesmo de utilizar procedures e functions com diferenças nos parâmetros e tipos de retorno.
A orientação a objetos veio para resolver problemas semelhantes a esse, onde a classe pode ter métodos virtuais, de forma que ao instanciar a classe com um descendente da classe base, ao chamar o método, chamará a função correspondente. Mas, não é o que você pretende fazer.
No seu caso, a ideia é simplificar o código:
if <condição> then <método 1> else <método 2>;
Para:
Operador(<condição>, <método 1>, <método 2>);
Se pararmos para pensar, isso nem economiza nada. O if/then/else continua sendo necessário, mas interno à function/procedure, e seu código precisa executar mais uma chamada de procedure.
Dadas as limitações e o fato de que isto não simplifica tanto o código, eu não utilizaria esse tipo de recurso.
Responder
Gostei + 0
20/12/2023
Guilherme Lima
Entendo, no caso eu estava criando apenas para estudo mesmo, não seria para uma aplicação prática, mas valeu o esforço
queria só fazer isso pra procedures, pois para valores mais simples já tem o IfThen do próprio Delphi
queria só fazer isso pra procedures, pois para valores mais simples já tem o IfThen do próprio Delphi
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)