<br><br><div class="gmail_quote">2008/12/23 Luis Motta Campos <span dir="ltr">&lt;<a href="mailto:luismottacampos@yahoo.co.uk">luismottacampos@yahoo.co.uk</a>&gt;</span><br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="Ih2E3d">breno wrote:<br>
&gt; protótipos são uma espécie de verificação de argumentos em tempo de<br>
&gt; compilação, e permitem que vc chame subrotinas sem os parêntesis sem<br>
&gt; gerar ambiguidade, como as funções built-in do Perl (&quot;push&quot;, por<br>
&gt; exemplo). A declaração de protótipos não envolve o nome da variável<br>
&gt; onde vc pretende colocá-la, apenas o símbolo do tipo de variável ($,<br>
&gt; @, %, &amp;) que espera receber como parâmetros.<br>
<br>
</div>ERRADO.<br>
<br>
Protótipos não verificam nada sobre o conteúdo dos parâmetros passados.<br>
Não verificam nem mesmo se os parâmetros passados realmente existem.<br>
<br>
A terminologia clássica de computação usa o termo &quot;protótipo&quot; para<br>
indicar verificação cruzada de parâmetros passados para uma função,<br>
especialmente em linguagens fortemente tipadas.<br>
<br>
PROTÓTIPOS EM PERL SÃO ALGO COMPLETAMENTE DIFERENTE.<br>
<br>
Protótipos em Perl são uma transformaão implícita e forçada dos<br>
argumentos passados para uma função. Como efeito colateral desejável, o<br>
interpretador Perl apenas &quot;consome&quot; tantos argumentos quantos uma função<br>
prototipada declara aceitar.<br>
<br>
Exemplos:<br>
<br>
Esta é a implementação didática da função push() que eu uso para ensinar<br>
protótipos:<br>
<br>
sub ipush ( \@@ ) {<br>
 &nbsp;my $array_ref = shift;<br>
 &nbsp;@$array_ref = ( @$array_ref, @_ );<br>
}<br>
<br>
Esta função se comporta exatamente como o push, inclusive em termos de<br>
preservar a integridade de array do primeiro argumento.<br>
<br>
O Perl tenta fazer coercção controlada do primeiro argumento para algo<br>
que seja do &quot;tipo&quot; (no sentido de &quot;forma&quot;) descrito por &quot;\@&quot; (uma<br>
referência para um array). Os outros argumentos são &quot;coagidos&quot; a se<br>
tornarem um array (o que não faz muita diferença prática a não ser nos<br>
casos mais extremos).<br>
<br>
Assim, você pode invocar ipush(), passar um array como primeiro<br>
argumento e ter certeza de que ele vai ser preservado:<br>
<br>
ipush @stack, 1..5;<br>
<br>
Mas, se você tentar passar outra coisa para o ipush() como primeiro<br>
argumento, a coerção falha e o Perl reclama que o &quot;tipo&quot; (no sentido de<br>
&quot;forma&quot;) é incompatível:<br>
<br>
ipush \@stack, 1..10;<br>
<br>
resulta em<br>
<br>
Type of arg 1 to main::ipush must be array (not reference constructor)<br>
at tmp/ipush.pl line 12, near &quot;10;&quot;<br>
<br>
O que o Perl fez é completamente diferente do que as nossas mentes de<br>
programador tendem a entender e modelar para a gente: o Perl TRANSFORMA<br>
os argumentos para que eles combinem com o protótipo ANTES de os colocar<br>
na pilha de argumentos (@_, para os sem formação técnica em Ciências da<br>
Computação).<br>
<br>
Com isso, eu posso, por exemplo, preservar arrays quando da passagem<br>
deles para uma função (como no exemplo do ipush()), ou fazer outras<br>
&quot;mágicas&quot;, como implementar lenght() para arrays:<br>
<br>
sub ilenght ( $ ) { return shift; }<br>
<br>
Atenção que agora eu estou fazendo outro tipo de &quot;coerção&quot; do argumento.<br>
Desta vez, eu &quot;obrigo&quot; arrays a ter contexto escalar. E todo mundo sabe<br>
que um array em contexto escalar resolve para o número de elementos<br>
existentes no array.<br>
<br>
Assim,<br>
<br>
my @alpha = qw( a b c d e f );<br>
ilenght @alpha;<br>
<br>
Retorna, obviamente, 6.<br>
<br>
Agora,<br>
<br>
ilenght qw( a b c d e f );<br>
<br>
Retorna &quot;f&quot;. Porquê? [1]<br>
<br>
Finalmente, você pode implementar if() com protótipos:<br>
<br>
sub IF ( $&amp; ) {<br>
 &nbsp;my ( $condition, $code ) = @_;<br>
 &nbsp;# ...<br>
}<br>
<br>
O que aceita<br>
<br>
IF $boolean, \&amp;sub_name;<br>
<br>
mas não gosta de<br>
<br>
IF $boolean, { code_here; };<br>
<br>
Deixo como exercício para o leitor interessado descobrir como criar um<br>
protótipo que aceite blocos de código, interessante para criar<br>
Linguagens Específicas para um Domínio de problema, ou DSL, da sigla em<br>
inglês para /Domain/ /Specific/ /Language/.<br>
<br>
Eu poderia falar muito mais sobre exemplos de protótipos, mas acho que<br>
estes já são o bastante para vocês saberem que eu já dei as minhas<br>
cabeçadas neste assunto.<br>
<br>
Agora, vamos falar de boas práticas: vocês gostariam de ter de manter um<br>
código cheio de efeitos colaterais irritantemente complexos como os que<br>
você pode conseguir chamando múltiplas combinações de funções com<br>
protótipos encadeadas? Eu não.<br>
<br>
Protótipos são uma tecnologia poderosa. O problema é que tanto poder<br>
termina por ajudar você a não tremer quando você tenta atirar no dedão<br>
do pé. Eu, particularmente, prefiro usar técnicas que me impeçam de<br>
tentar atirar no dedão do meu pé...<br>
<br>
A minha recomendação é: a não ser que você tenha uma situação<br>
extremamente difícil e altamente controlada, você deve fazer as<br>
transformações à mão, durante a chamada de cada função que você<br>
escrever. Assim, não vão existir efeitos colaterais implícitos para te<br>
deixar louco debugando programas até as três da manhã.<br>
<br>
Eu praticamente não uso protótipos de funções em lugar nenhum no meu<br>
código. Especialmente quando eu estou dando manutenção em outros sistemas.<br>
<br>
Espero que as coisas estejam mais claras agora. Perguntem, meus<br>
queridos. Perguntem.<br>
<br>
Putamplexos.<br>
<font color="#888888">--<br>
Luis Motta Campos is a software engineer,<br>
Perl Programmer, foodie and photographer.<br>
<br>
<br>
[1] uma lista em contexto escalar, ao contrário de um array, resolve<br>
para o último elemento da lista.<br>
</font><div><div></div><div class="Wj3C7c">_______________________________________________<br>
SaoPaulo-pm mailing list<br>
<a href="mailto:SaoPaulo-pm@pm.org">SaoPaulo-pm@pm.org</a><br>
<a href="http://mail.pm.org/mailman/listinfo/saopaulo-pm" target="_blank">http://mail.pm.org/mailman/listinfo/saopaulo-pm</a><br>
</div></div></blockquote></div><br><br clear="all"><br>Você se incomodaria se eu compilasse o que você escreveu e começasse a preparar um documento para submeter à documentação do perl sobre protótipos? Eu ando inspirado para escrever, gostaria muito de contribuir com isso.<br>
<br>Cheers!<br><br><br>-- <br>André Garcia Carneiro<br>Analista/Desenvolvedor Perl<br><br>