[SP-pm] Módulo

Luis Motta Campos luismottacampos em yahoo.co.uk
Terça Março 6 09:01:31 PST 2007


On Mar 6, 2007, at 5:38 PM, Thomas Britis wrote:
> Boa tarde Luis,
>
> 	Obrigado pela resposta e pelo tempo despendido com isso.
>
> 	Esta foi apenas uma questão hipotética e com certeza foi um tanto
> quanto confusa minha colocação.
>
> 	Na prática o que eu quero é automatizar algumas funções que, por  
> vezes
> tenho que utilizar. Isso inclui acessos à banco de dados ou protolos
> específicos (as vezes utilizando módulos do cpan). Minha dúvida  
> surgiu,
> inicialmente, pela necessidade de tratar o retorno de alguma função do
> módulo de forma diferente.

   A palavra que você tem de procrar na internet é "desacoplamento"  
ou "unco[u?]pling" em inglês.
   Esta é a "ciência" de projetar bons objetos (versáteis e reusáveis).

> 	Exemplificando:
> Em um determinado programa eu preciso fazer uma conexão com um  
> banco de
> dados e, em caso de falha, pouco me importa o porque. Apenas saber  
> que a
> conexão falhou já me basta. E isso eu consigo facilmente utilizando
> valores de retorno da função de conexão ao banco.
> Porém, em uma segunda hipótese eu preciso tratar o erro que me é
> retornado. E, sem quebrar a estrutura inicial (utilizando valores
> numéricos de retorno), eu precisaria saber o erro. Então pensei em
> utilizar a mesma estrutura do módulo, algo como:
>
> sub connect {
>   my $self = shift;
>
>   if (!connect_to_db()) {
>      $self->{mensagem_de_erro} = 'Erro específico';
>      return 0;
>   }
>   return 1;
> }
>
> 	Com isso eu resolveria os dois problemas. Teria o retorno e a  
> mensagem
> de erro, caso esta fosse necessária.
>
> 	Lembre-se que esta é uma situação hipotética e simples. Mas, se eu
> conseguir entender qual a melhor maneira de se fazer isso, terei
> resolvido diversos outros problemas estruturais e poderei começar a
> desenvolver meus módulos tranquilamente.

   Quando você fala em "problemas estruturais", está preocupado em  
não alterar a sua interface de programação pré-estabelecida, certo?

   Bom, aqui cabe uma coisa para pensar, e para você equilibrar  
dentro do seu sistema:

   Compatibilidade Retroativa é a coisa mais quebrada dentro do MS  
Windows.

   Se eles jogassem fora as coisas ruins, teriam muito menos  
"problemas estruturais" do que eles tem.

   Este é um jogo de equilíbrio, Thomas, entre o que você acha que é  
interessante manter (não estou questionando seus motivos, qualquer  
motivo serve) e o que você realmente vai manter (para não se afogar  
em "problemas estruturais" gerados pela sua tentativa de manter o  
projeto retroativamente compatível com tudo).

> 	Na prática a dúvida é: se eu receber a hash como argumento da  
> função e
> alterá-la, essa alteração terá validade apenas dentro dessa função ou
> dentro da função que a chamou também?

   Se você receber uma referência para o hash table, está alterando a  
própria.
   Se receber uma cópia da hash table, está alterando a cópia (e vai  
perder a alteração quando a cópia for reclamada pelo Garbage  
Collector, no final do escopo).

> 	Ou ainda:
> sub connect {
> 	my $self = shift;
>
> 	if (!connect_to_db()) {
> 		$self->{mensagem_de_erro} = 'Erro';
> 		return 0;
> 	}
> 	return 1;
> }
>
> 	Teria o mesmo efeito que:
> sub connect {
> 	my $self = shift;
>
> 	if (!connect_to_db()) {
> 		$self->{mensagem_de_erro} = 'Erro';
> 	}
> 	return $self;
> }
> 	?????

   Claro que não.
   Num caso, você tem retornos numéricos (e eu presumo que assuma e  
teste retornos numéricos em algum lugar do seu código, certo?)
   No outro caso, você tem retorno objetivo - o efeito colateral mais  
importante disto é que te permite encadear chamadas a outros métodos,  
assim:

   $obj->method()->method2()->method3();

   Coisa que, com retorno numérico não se pode fazer, por razões  
óbvias. ;-)

   Claro que, se a tua especificação de interface convencionar  
"boolean", e não permitir a ninguém assumir mais nada a respeito dos  
valores do módulo que não "true" para sucesso e "false" para  
fracasso, ambos os módulos são idênticos. Mas lembre-se: apenas no  
caso da tua interface estar corretamente especificada, e o Perl não  
vai fazer nenhum esforço no sentido de impedir alguém de descobrir e  
usar o valor booleano que você passou na interface (quer seja um  
objeto, ou um número) como tal.

> 	Espero ter sido um pouco mais claro agora.
> 	E, novamente, obrigado pelo tempo perdido com a resposta.

   Você foi muito mais claro, desta vez.
   O tempo já não foi "perdido" foi doado para melhorar e aumentar o  
teu conhecimento ;-)
   Eu fico feliz em dispender tempo quando vejo que ele é bem-usado.

   Recomendo que você leia mais sobre Projeto Orientado a Objetos, e  
tenha menos medo de fazer alterações.
   Sim, quebrar código velho faz parte do processo, e a gente tem  
apenas de ter certeza de que consertou tudo o que a nossa alteração  
de desenho quebrou. ;-) Para isso, use testes.

   Putamplexos, boa sorte, e mantenha a gente informado sobre os teus  
progressos.
--
Luis Motta Campos is a software engineer,
perl fanatic evangelist, and amateur {cook, photographer}




Mais detalhes sobre a lista de discussão SaoPaulo-pm