[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