[SP-pm] Chamando subrotinas com "&" ou sem "&" (ou: "meus deuses, o que foi que eu fiz?"
Estevam Brayn
estevambrayn at gmail.com
Wed Nov 19 05:07:30 PST 2008
Segue minha contribuição, espero que seja útil. Agora é voltar ao batente.
Se alguém agora puder assumir o resto da tarefa, agradeço. Realmente tão
cedo não terei mais tempo de lidar com isto.
Tive algumas dificuldades, especialmente para traduzir "built in functions"
(coloquei funções pré-definidas, mas acho que pode dar confusão com funções
previamente definidas pelo programador); sigil, que traduzi como "símbolo",
embora acho que seria mais correto traduzir como "signo", mas achei que
ficaria estranho no contexto; "the inlining of constants", nem traduzi pois
não faço a mínima idéia do que seja.
Bem, lá vai:
----------------------------
Subrotinas chamadas com o "e comercial"
Subrotinas chamadas com o "e comercial"
Chamar subrotinas com "es comerciais" é um sinal de Perl
antigo<http://www.perlfoundation.org/perl5/index.cgi?ancient_perl>.
Esta página visa descrever por que este foi comum uma vez, o que está errado
com ele, e o que você pode fazer para consertar seu código fonte legado.
A propósito, se você não sabe o que é um "*e comercial*": o caracter & é
chamado um "e comercial".
História: Um símbolo para subrotinas
O Perl tem símbolos <http://www.perlfoundation.org/perl5/index.cgi?sigil>que
indicam o tipo de dado de uma variável. Os símbolos têm sido os mesmo
através da história do Perl e praticamente gravados em pedra.
Símbolo
Exemplos
Usado para
$
$foo
$foo[42]
$foo{'bar'}
Elementos únicos: escalares (incluindo elementos de array e hash)
@
@foo
@foo[23, 42]
@foo{'bar', 'baz'}
Elementos múltiplos: arrays e [pedaço]s of arrays e hashes
%
%foo
Hashes
*
*foo
*foo{SCALAR}
*foo{HASH}
Entradas de Tabela de
Símbolos<http://www.perlfoundation.org/perl5/index.cgi?symbol_table>("[typeglob]s")
&
&foo
&foo($bar, $baz)
Subrotinas
O modo básico de criar uma subrotina não mudou desde o Perl 1. A palavre
sub, seguida do nome da subrotina, e então o bloco de código (incluindo as
chaves)
sub foo {
# some code here, that receives the
# arguments passed to the sub
# in the special array @_.
}
O modo de *chamar* a subrotina (voce poderia dizer *executar* a subrotina)
mudou. Aliás, duas vezes!
No início do Perl, as subrotinas eram chamadas com a palavra pré-definida *
do*. Embora *do* ainda esteja no Perl hoje, e ainda suporte esta sintaxe
muito antiga, quando você vê *do* em código moderno, será praticamente
sempre *do $filename* ou *do BLOCK*.
# This is how you would call a sub called "foo" in Perl 1
do foo ("argument 1", "argument 2");
Posteriormente, as subrotinas ganharam um símbolo, um marcador visual para
indicar seu tipo. Isto permitiu o uso de uma subrotina sem a palavra *do*, e
fez o código parecer muito mais natural. O símbolo para subrotinas era o "e
comercial", &. Embora a definição da subrotina não tenha ganho o símbolo,
praticamente toadas as chamadas a subrotinas estavam logo sendo feitas
com *&foo("argument
1", "argument 2")* ao invés de *do foo ("argument 1", "argument 2")*.
Há algo especial sobre o modo *&foo* de chamar subrotinas, que tem a ver com
se você usa ou não parênteses. Usar *&foo* sem parênteses faz o Perl passar
adiante o* @* _ *corrente* como argumentos da chamada de subrotina. Isto
significa que há um enorme diferença entre *&foo* e *&foo()*.
Por que é ruim agora
O Perl novamente ganhou uma nova sintaxe para chamar subrotinas no Perl 5. O
mesmo que o jeito antigo, mas sem a palavra *do*. Qualquer palavra não
reservada <http://www.perlfoundation.org/perl5/index.cgi?bareword> seguida
de parênteses é agora vista como uma chamada de subrotina e fechou mais o
espaço entre funções pré-definidas (freqüentemente chamadas "named
operators"). Não apenas o *&* tornou-se opcional, os parênteses podiam agora
ser deixados completamente de fora se a subrotina fosse
predeclarada<http://www.perlfoundation.org/perl5/index.cgi?predeclared>.
Ao mesmo tempo, Perl ganhou
protótipos<http://www.perlfoundation.org/perl5/index.cgi?prototypes>,
que tornou possível imitar a sintaxe de funções pré-definidas para funções
escritas em Perl. Protótipos também são frequentemente usados para assegurar
um certo número de argumentos, mas este uso de protótipos permanece
controverso até hoje.
O antigo estilo *&foo* não suporta protótipos, mas você ainda pode chamar
subrotinas que têm protótipos com ele. O protótipo é ignorado. Isto é
potencialmente perigoso, porque a subrotina pode contar com o protótipo para
fazer coisas para ela. Além disso, faz a forma "e comercial" desabilitar
otimizações como the inlining of constants.
Por *&foo* estar ficando fora de estilo, a muitos programadores não é mais
ensinada a diferença entre usar parêteses com ele e omiti-los. Bugs causados
por pessoas que usam *&foo *e pensaram que faria o mesmo que *&foo()* podem
ser bem difíceis de encontrar e depurar.
Mas muitas pessoas pressionarão você a mudar seu estilo carregado de "es
comerciais" para o visual moderno mais limpo apenas porque eles acham os
velhos "es comerciais" uma coisa feia que atrapalha. *Há* algum valor em
estética de código!
Bons usos de &foo
Ainda há bons usos de &foo. Em geral, o símbolo & é correto quando você está
*fazendo referência à subrotina, mas não a está chamando*. Alguns exemplos:
defined &foo
undef &foo
\&foo
Praticamente é sempre ruim quando você está chamando a subrotina.
Entretanto, *&foo* é levemente mais eficiente que *foo(@_)*. Se você está
usando esta (micro-)otimização, certifique-se de adicionar um comentário que
indica que você sabe o que está fazendo, algo como:
&foo; # otimização: passar @_ eficientemente
Consertando seu código
Para melhorar seu código, simplesmente encontra todas as ocorrências de "e
comercial" na frente de um nome de subrotina e, a não ser que seja um dos
bons usos listados, simplesmente remova o "e comercial". Note que um
*&foo*pelado, sem argumentos e
*sem parênteses* se traduz em *foo(@_)*, se você quer mudar este (ainda
perfeitamente aceitável) uso também.
Chamar uma subrotina por uma referência a ela ao invés de seu nome é feito
melhor com o operador
flecha<http://www.perlfoundation.org/perl5/index.cgi?arrow%20operator>,
*->*.
Antes
Depois
&foo()
foo()
&foo($arg1, $arg2)
foo($arg1, $arg2)
&foo
foo(@_)
(&foo é aceitável se comentado)
&$subref()
$subref->()
&$subref($arg1, $arg2)
$subref->($arg1, $arg2)
&$subref
$subref->(@_)
Note que esta é "apenas "uma melhoria de estilo. É muito improvável
aumentar o desempenho do seu programa de modo que se note, isso se aumentar.
-------------------------------------------
2008/11/19 Estevam Brayn <estevambrayn em gmail.com>
> Eu sou voluntário, MAS:
>
> Eu apenas acompanho as discussões aqui, não programo e nem trabalho com
> isto.
> Por isto, ofereço-me para fazer uma tradução inicial e depois posto aqui
> para que os amigos façam uma revisão dela, principalmente porque não conheço
> bem os termos técnicos em português. E também não tenho a mínima idéia de
> como formatar e colocar no perl.org.br.
> Eu sempre tenho vontade de colaborar aqui mas nunca tenho conhecimento
> suficiente para participar das discussões, então espero ajudar traduzindo.
> Bem, vou começar.
> Abraços!
>
> 2008/11/19 Luis Motta Campos <luismottacampos em yahoo.co.uk>
>
>> Gente,
>>
>>
>> por causa das minhas perguntas na lista, apareceu um documento novo no
>> Wiki do Perl 5:
>>
>>
>>
>> http://www.perlfoundation.org/perl5/index.cgi?subroutines_called_with_the_ampersand
>>
>> Ele contém a história completa (em inglês).
>>
>> Traduzir isso para pt_BR e publicar no perl.org.br pode ser uma coisa
>> interessante e importante para fazer.
>>
>> Alguém é voluntário?
>>
>> Putamplexos!
>> --
>> Luis Motta Campos is a software engineer,
>> Perl Programmer, foodie and photographer.
>> _______________________________________________
>> SaoPaulo-pm mailing list
>> SaoPaulo-pm em pm.org
>> http://mail.pm.org/mailman/listinfo/saopaulo-pm
>>
>
>
-------------- Pr?xima Parte ----------
Um anexo em HTML foi limpo...
URL: <http://mail.pm.org/pipermail/saopaulo-pm/attachments/20081119/834e7bef/attachment-0001.html>
More information about the SaoPaulo-pm
mailing list