[SP-pm] Entendendo Protótipos

Daniel de Oliveira Mantovani daniel.oliveira.mantovani at gmail.com
Tue Dec 23 04:25:41 PST 2008


Tio obrigado, era uma explicação assim que eu queria.


sub ipush ( \@@ ) {
 my $array_ref = shift;
 @$array_ref = ( @$array_ref, @_ );
}

Eu não compreendi o que é isso ."\@@"
Você diz que \@ é uma referência e que o resto é forçado a se transformar em
um array.

Vou tentar resolver aquele problema que você passou.

[]s

2008/12/23 Luis Motta Campos <luismottacampos em yahoo.co.uk>

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



-- 
http://mantovanihouse.blogspot.com/

-------(\_------------_/)-----------
-------)--(----------)--(-----------
------(----(---------)----)----------
-------)----(-------)----(-----------
-------(----(-------)----)-----------
--------\_-(\\.---.//)-_/------------
----------\)' -8--8- '(/--------------
-----------/------------\---------------
----------(--)--------(--)--------------
------------(_c__c_)----------------
----------------------------------------
-------------- Pr?xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20081223/85a1ec54/attachment-0001.html>


More information about the SaoPaulo-pm mailing list