2008/11/15 Luis Motta Campos <span dir="ltr"><<a href="mailto:luismottacampos@yahoo.co.uk">luismottacampos@yahoo.co.uk</a>></span><br><div class="gmail_quote"><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">Daniel de Oliveira Mantovani wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
no caso de uma sub rotina se faz que nem na linha 19, eu sei fazer,<br>
só que eu não sei o porque!<br>
<br>
Alguém pode me dar uma explicação técnica?<br>
</blockquote>
<br></div>
Sem comentários sobre você insistir em usar o Deitel. É lamentável, ele tem vícios e conceitos errados. Você não deveria. Mas é a tua cabeça, e você parece teimoso.</blockquote><div>Enquanto não chega mês que vem pra ter o livro Programação Perl, eu fui folhando este. <br>
</div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
Sobre referências: o Deitel não explica nada sobre como marcar variáveis, certo? Assim, você perdeu um conceito importante, que é base para entender referências.<br>
<br>
"$lista", na verdade, é uma abreviação. Formalmente, as variáveis em Perl são marcadas com os operadores "${}", "@{}", e "%{}". Assim, a forma "longa" da sintaxe correta de Perl para dizer "$lista", na verdade, é "${lista}".<br>
<br>
Isso é uma herança da implementação do shell, onde a gente pode manipular os nomes das variáveis sem precisar de uma outra variável para conter o "nome". Em perl, para fazer isso, podemos usar strings ou expressões. Por exemplo:<br>
<br>
$nome = 'lista';<br>
${ $nome } = [ 1, 2, 3, 4, 5 ]; # mesma coisa que "$lista = ..."<br>
<br>
$counter = 1;<br>
${ 'nome' . $counter } = 'valor'; # mesmo que "$nome1 = 'valor';"<br>
<br>
Assim, todas as variáveis em Perl tem duas partes distintas: um "container", que indica o tipo de variável, e um "nome", que vai dentro do container e especifica qual é entrada da tabela de símbolos do Perl que eu quero usar.<br>
<br>
Oras, referências são simplesmente variáveis que contém um ponteiro para outro elemento da tabela de símbolos. Ou, em palavras mais simples: uma variável que contém a parte do "nome" de outra variável. Assim, se eu quiser, posso aplicar dois containers na mesma variável, em seguida, e obter o valor referenciado:<br>
<br>
@{ ${ lista } } = ( 1, 2, 3, 4, 5 );<br>
<br>
Ou, abreviadamente:<br>
<br>
@$lista = ( 1, 2, 3, 4, 5 );<br>
<br>
Note que o container externo e o container interno são de tipos diferentes: o Perl não se importa, já que você está falando apenas de elementos da tabela de símbolos - que são todos definidos pela mesma estrutura básica.<br>
<br>
Assim, podemos também ter uma função que ŕetorna o símbolo que a gente quer usar:<br>
<br>
sub get_list { return $lista }<br>
<br>
print @{ get_list() }; # imprime "12345"<br>
<br>
# NÃO POSSO abreviar este como<br>
# print @get_list();<br>
# Você sabe dizer por quê? :)<br>
<br>
Note que eu precisei usar "()" no nome da função, ou o Perl ficaria muito confuso e sem saber se o nome que está dentro do container "@{}" é uma chamada de subrotina ou um nome na tabela de símbolos. Os parêntesis fazem o perl interpretar aquele nome como uma subrotina automágicamente.<br>
<br>
Mas isso ainda não é de-referenciar funções. O que você está de-referenciando aqui é o valor retornado por uma função.<br>
<br>
Para de-referenciar funções, você precisa primeiro saber que funções tem um tipo e um container também, mas que ele é implícito. O container para funções pode ser escrito explicitamente como "&{}". ATENÇÃO: por diversas razões, ao longo do desenvolvimento da linguagem, a gente parou de escrever "&funcao( $argumento )" e passou a usar a forma mais flexível "funcao( $argumento )". Assim, usamos o símbolo "&{}" apenas para falar sobre a entrada na tabela de símbolos correspondente àquela subrotina. Por exemplo:<br>
<br>
sub faz_coisas { return "feito"; }<br>
# para chamar faz_coisas, usamos<br>
$feito = faz_coisas;<br>
# e o perl sabe o que fazer com isso.<br>
<br>
Para fazer uma referência para faz_coisas, devemos informar o Perl que estamos falando explícitamente da entrada na tabela de símbolos, e que não queremos executar a função. Para isso, usamos o container de subrotina:<br>
<br>
$ref_faz_coisas = \ &{ faz_coisas };<br>
<br>
Note que eu usei uma "bareword" para indicar o nome da função, o que é perfeitamente válido. Poderia ter escrito também<br>
<br>
$ref_faz_coisas = \ &{ 'faz_coisas' };</blockquote><div><br>Agora deu para entender. <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
<br>
Ainda falta um detalhe. Você deve estar se perguntando por que é que o operador de criação de referência ('\') aparece aqui. Bom, se você apenas mencionar a entrada na tabela de símbolos para uma função, o operador de perl vai substituir ela pelo valor, e executar a função para você.<br>
<br>
Isso quer dizer que escrever "&{ faz_coisas }" ou "&{ 'faz_coisas' }" sem mencionar o operador de referência faz o perl buscar o valor de 'faz_coisas' na tabela de símbolos, e depois resolver a expressão, executando a função chamada.<br>
<br>
Agora temos dois jeitos de armazenar referências para funções: podemos usar um nome, e forçar um /lookup/ na tabela de símbolos (lento, lento, lento, mas muito flexível) ou podemos armazenar uma "referência de verdade" para uma função. Exemplo:<br>
<br>
# com um nome e /lookup/:<br>
&{ 'faz_coisas' }( 'argumento1', 'argumento2' );<br>
<br>
# ou, com uma referência de verdade:<br>
$ref = \ &faz_coisas; # criando referencia com o operador '\'<br>
$ref->( 'argumento1', 'argumento2' ); # chamando a função<br>
</blockquote><div><br>No livro tem explica meio por cima, não desse jeito, aí da um nó na cabeça, você fica se perguntando "Como Perl faz isso ?!". <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
É isso. Agora você sabe por que o Deitel é uma merda: ele não explica coisas básicas e me faz escrever estes emails longuíssimos.<br>
</blockquote><div><br>:P <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><br>
Espero que isso ajude a entender o que você perguntou.</blockquote><div><br>Sim você ajudou, muito e muito, obrigado<br><br>[]'s <br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<br>
Putamplexos.<br><font color="#888888">
-- <br>
Luis Motta Campos is a software engineer,<br>
Perl Programmer, foodie and photographer.</font><div><div></div><div class="Wj3C7c"><br>
_______________________________________________<br>
SaoPaulo-pm mailing list<br>
<a href="mailto:SaoPaulo-pm@pm.org" target="_blank">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></div></div></blockquote></div><br><br clear="all"><br>-- <br>print "\x54\x68\x65\x20\x53\x69\x6c\x65\x6e\x74\x20\x47\x75\x61\x72\x64\x69\x61\x6e",$/<br>
<br>( Procuro emprego CV:<br><a href="http://www.4shared.com/file/71236573/2c80149/curriculo.html">http://www.4shared.com/file/71236573/2c80149/curriculo.html</a> )<br>