Pois é aqui buscamos duas coisas, uma é incentivar os desenvolvedores a documentarem e organizarem seu código, e a segunda é resolver a questão do erro Input parameter cannot be assigned.
'Melhores Práticas'
É uma pretensão gigante de minha parte criar aqui uma lista de melhores práticas de desenvolvimento, mesmo porque cada pessoa tem um perfil, cada empresa um padrão, ou seja, vamos direto ao ponto, que é como documentar os parametros utilizados para transferir informações de um lugar para outro.
Aprendi que existem dois tipos de pessoas no mundo, aquelas que fazem de tudo para esconder o que sabem e o que fizeram, e aquelas que sente prazer em falar o que sabe pra todo mundo. Infelizmente o segundo tipo acaba se dando mal em algumas situações, experiência própria. O primeiro tipo pensa o seguinte, vou programar de forma que somente eu possa entender o programa, assim, fico garantido porque ninguem mexe comigo, rs...., pode ser também uma questão de extrema desorganização, falta de tempo, ou seja, uma série de desculpas para não deixar a "coisa clara". Vamos ao exemplo, citando um amigo ficticio que chamaremos de Mario, cujo perfil é, mais ou menos, do primeiro tipo de pessoa.
Certo dia, o Mario chegou pra trabalhar em sua empresa e tinha que programar uma rotina complexa em uma procedure, algo relacionado a faturamento, impostos, ..., e como tinha que passar um montão de parametros, escreveu algo semelhante a:
parm(&invc, &xkpt, &sbtrr, &isn, &kkrg, &aaiins, &inss, &ir, &sbtstr, &opt1, &opt2, &opt3);
Nada muito complexo, sob a ótica do Mario, mesmo porque a procedure tratava todos esses parâmetros, com um extenso código de1200 linhas, mas que ele tinha tudo na cabeça, e claro, conhecia linha por linha desse procedimento e sabia exatamente o que tinha que passar de informação e o que tinha de receber da procedure. Já viu algo assim? pois é um dia eu vi e reforçou o que eu já fazia antes, que era programar de forma clara, mesmo porque levei dois dias para interpretar o que o Mario queria dizer com cada uma das variáveis malucas criadas.
Nem vou dizer a respeito de comentários de código, sub-rotinas documentadas e coisas do gênero, vamos apenas buscar melhorar a lista de parametros. Desta forma, acredito, na minha humilde e singela opinião, que uma prática melhor seria programar algo assim:
parm(
&invc, // indice
de variacao
&xkpt, //
pre-calculo final
&sbtrr, // valor da
substituicao trib.
&isn, // valor
do imposto recebido
&kkrg, // valor
interno de calculo
&aaiis, // previa do iss
&iss, //
imposto iss calculado
&ir, //
imposto ir calculado
&sbtstr, // valor final
da subst. trib
&opt1, // opcao
de calculo com ir
&opt2, // opcao
de calculo com iss
&opt3 // opcao
de calculo com subst.
);
'Input parameter cannot be assigned'
Vamos ao erro que motivou o post, Input parameter cannot be assigned, que quer dizer o seguinte, todo parametro recebido no parm não pode ser atribuido um valor diferente. É causado toda vez que um parâmetro é envolvido em uma operação que altera seu valor, como no exemplo a seguir.
parm(&a, &b, &c);
&a = &a+1
&b = &b*&a
&c = &s+&b
Desta forma, se não se informa o contrário, todo parâmetro é de entrada, e não aceita alterações em seus valores. E nessa lógica, se existe o conceito de parametro de entrada, temos também o conceito de parametros de saída e de entrada e saída. E é exatamente para isso que servem os flags in:, out:, inout: providos pelo Gx.
O mais interessante é que parametros do tipo inout: tanto podem receber informações quanto devolver valores calculados, ou seja, a declaração do parametro desse tipo é suficiente para remover a mensagem Input parameter cannot be assigned.
Ja pensou então se definissemos
no parm do Mario
quais os parametros que seriam fornecidos a procedure, e quais a procedure nos
devolveriam? Teriamos um código melhor mesmo, porque não precisariamos ligar
toda hora pro Mario para perguntar o que é tal coisa.
parm(
in: &invc, // indice de variacao
out: &xkpt, // pre-calculo final
out: &sbtrr, // valor da substituicao trib.
in: &isn, // valor do imposto recebido
in: &kkrg, // valor interno de calculo
inout: &aaiis, // previa do iss
out: &iss, // imposto iss calculado
out: &ir, // imposto ir calculado
out: &sbtstr, // valor final da subst. trib
in: &opt1, // opcao de calculo com ir
in: &opt2, // opcao de calculo com iss
in: &opt3 // opcao de calculo com subst.
);
Enfim, parametros de saída são aqueles que em uma chamada com Call podem receber valores.
Tenho usado, na maioria das vezes, esse tipo de programação, e salvo a própria complexidade das rotinas programadas, acredito que a clareza e a documentação do código sejam práticas fundamentais para o sucesso nos projetos.
Agora muito cuidado com a história do Mario e do armário hein...
Um comentário:
Caramba,
Agora que eu vi, hoje é 11/11/11, que sinistro hein...
Postar um comentário