Conforme havíamos conversado no sábado a respeito de metodologias, é sempre bom lembrar que há várias formas de se fazer a mesma coisa. Nos extremos, a pior e a melhor forma. Quando melhor fizermos, tanto menor será o problema futuro com manutenção, por exemplo. Por isso sempre frizo que é de grande importância observar como escrevemos nossos códigos. A questão da sua variável VRET é um exemplo do que digo. Você disse que "toma cuidado" para não causar conflitos com nomes. Pena que somos falíveis. E às vezes a coisa "passa" e não percebemos. Como se trata de um erro sutil, por vezes é difícil detectar a origem. Foi bem o caso que comentei.
A linguagem XBase é fraca e não há o menor rigor com a tipagem. Se isso existisse, problemas desse tipo não aconteceriam. Acho que a melhor solução para isso é desenvolver e praticar boas metodologias. Talvez não consegamos desenvolver sempre o melhor, mas pelo menos não faremos o pior código.
Por anos a fio a ciência da computação foi aperfeiçoando práticas e metodologias de desenvolvimento de software, sempre mirando o máximo em nível de qualidade, tanto do desenvolvimento como nos demais processos que ocorrem ao longo da vida do software. Manutenção incluída. Muitos autodidatas pulam certas fases de aprendizado por conta do imediatismo. Com isso, acabam criando vícios e conceitos bobos, como o caso que comentamos há pouco tempo sobre sempre precisar existir um ELSE para cada IF ou que uma função só deveria ter um RETURN. Conceitos bobos e deturpados como esses só levam a perda de tempo. Não acrescentam nada e criam vícios. Se milhares de programadores em todo o mundo fazem diferente deve ser porque eles estão certos.
Claro que o exemplo postado foi feito rapidamente apenas para poder ajudar o colega em dificuldade. Além do que a idéia era fazer algo muito simples e de fácil compreensão. Mas vamos pegar esse código assim mesmo, para ilustrar alguns conceitos.
Código: Selecionar todos
FUNCTION ESTADOS(opc)
IF ASCAN(aMenu1,opc)=0
@ 24,00 SAY PADC("Sigla UF, incorreta. Tente novamente.",80)
RETURN .F.
ELSE
RETURN .T.
ENDIF
Funciona. Mas cito duas falhas comuns de se ver. Uma função de checagem é como uma caixa-preta. Não deveria fazer outra coisa a não ser a checagem. Aqui vemos duas tarefas sendo executadas: a checagem e o alerta visual. Se amanhã ou depois houver alguma alteração na interface, o alerta visual desta, e de todas as demais funções do programa que fazem algo do tipo, deverão ser alteradas uma a uma.
A segunda falha é justamente o ELSE desnecessário. Duvido que o compilador Clipper, e mesmo o XHarbour, seja inteligente o suficiente para perceber a falha e eliminar esse ELSE automaticamente na compilação. Código desnecessário que, estando numa malha, fará o programa ficar mais lento. Uma alternativa:
Código: Selecionar todos
//--------------------------------------------
function bla...bla...bla... // alto nível
get cUF ...
read
if !ExistUF(cUF)
// Alerta por meio de função global única
// ErrorWarn("UF não encontrada!")
end
return nil
//--------------------------------------------
function ExistUF(cUF) // apoio
return cUF $ "XX,YY,ZZ,..."
Já ficou melhorzinho. Como é um exemplo simples, pode dar a impressão de não ser tão necessário. Mas à medida em que as coisas vão ficando mais complicadas, essa metodologia se mostra mais vantajosa.
Note que agora a função de pesquisa, que serve de apoio à função de alto nível, desempenha apenas uma tarefa. Pra qualquer função que a utilize existe apenas uma entrada: o valor de teste. E uma única saída: o resultado do teste. Só há uma hipótese da necessidade de alterar essa função: a criação ou extinção de um Estado. Fora isso, ela é uma caixa-preta. Ninguém precisa saber o que acontece dentro dela, mas apenas os argumentos de entrada e o valor de retorno.
A função global de alerta segue o mesmo estilo. É ela que tem vínculo com a geometria e as particularidades da interface, não a função que a utiliza. Isso se chama abstração. Se algo tiver que ser alterado na interface, você não terá que correr todo o seu código fonte para modificar função por função. Você só precisará ir a um lugar: o sub-sistema que cuida da interface.
O exemplo poderia ser mais elaborado para enfatizar melhor esses conceitos, mas eu só estava esperando uma pessoa aqui em casa e resolvi escrever um pouco a respeito do que havíamos conversado.
Não espero mudar a vida de ninguém, mas se conseguir deixar uma pulga atrás de orelha de uma única pessoa que seja, já terá valido a pena.
