Veja nesta publicação como tratar possíveis colisões de funções com o mesmo nome, e como ajustar comportamentos padrões das funções
da biblioteca Magic xpa.
A modularização das soluções Magic xpa é um recurso razoavelmente antigo (em termos de tempo de disponibilização) na plataforma, através do sistema de “Components“.
Data dos anos 2000, no saudoso eDeveloper 9, e permite que possamos exportar objetos de um módulo (cabinet) da solução, para utilização (reaproveitamento) em outro módulo. Veja:
E dentre os grupos de objetos que podemos expor para outros módulos, estão as “Developer Functions“.
As funções customizadas que criamos em um determinado cabinet podem ser exportadas e disponibilizadas para uso em outros cabinets (cabinet = .ECF).
Pois bem. Vejamos então o seguinte cenário:
Temos 2 componentes que por “coincidência” estão exportando funções com o mesmo nome, embora, cada uma possa fazer uma coisa diferente e dar um resultado também diferente.
Mas ambas acabaram tendo o mesmo nome:
No exemplo acima, temos 2 módulos (.ECFs) distintos que publicam uma função de nome “FunctionOverrideTest“.
Se usarmos estes 2 componentes em uma determinada solução e quisermos invocar esta função, qual das “duas” será de fato acionada ? 🙄
A resposta é: a que estiver no módulo (.ECF) que o Magic xpa Runtime carregou por último.
Se o componente “B” foi o último carregado, a função definida nele é a que será executada:
Mas se carregarmos o componente “A” por último, a dele é a que será executada:
Simples?. Sim.
Mas não termina por aqui.
Overriding em modo “hard”
Uma coisa que também podemos fazer, e criar “Developer Functions” que possuam o mesmo nome de funções standard da biblioteca do Magic xpa. Isso é permitido.
E neste caso, como as “Developer Functions” são carregadas depois da biblioteca standard do Runtime, elas tem a preferência na execução.
Veja este exemplo:
Foram criadas funções de nome “Date” e “Time“, que são também funções da biblioteca standard da plataforma.
Mas com lógicas totalmente diferentes: retornam dados totalmente aleatórios para ano, mês, dia, hora, etc …
Considerando a lógica mencionada mais acima, da ordem de carga das funções, estas 2 tomam o lugar das suas respectivas standard homônimas.
De maneira que sempre que utilizarmos “Date” e “Time” em alguma expressão neste programa (ou programas chamados a partir dele):
serão estas funções customizadas que estarão sendo acionadas:
Com grandes poderes, vem grandes responsabilidades
Refazer funções da biblioteca da plataforma, com outra lógica, é algo que sempre deve ser pensado com a devida cautela.
Especialmente porque o Magic xpa não disponibiliza o recurso inherited (invocar a rotina original de dentro da rotina que está fazendo o overriding).
O exemplo acima foi apenas para exemplificação. O correto seria ter-se criado funções “RandomDate” e “RandomTime“, por exemplo, para este fim (se houvesse de fato esta necessidade).
Mas é um recurso poderoso, que pode resolver algumas situações mais complexas.
Por exemplo: certa vez estava-se utilizando um componente de terceiro para executar uma determina regra de negócio. E a data e hora eram utilizadas nessa lógica, porém não eram informações parametrizáveis. O componente utilizava sempre as funções “Date” e “Time” para obter estas informações.
Como surgiu a necessidade de executar esta regra de negócio, porém de forma retroativa, a solução viável foi o override de “Date” e “Time” para retornarem informações do passado quando acionadas. 😉
Baixe agora um projeto exemplo Magic xpa 3.3x deste endereço, e usufrua de mais esta facilidade Magic.
Para receber os artigos do Blog Magic Brasil em primeira mão no seu email, registre-se aqui