2008/11/15 Luis Motta Campos <span dir="ltr">&lt;<a href="mailto:luismottacampos@yahoo.co.uk">luismottacampos@yahoo.co.uk</a>&gt;</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>
&quot;$lista&quot;, na verdade, é uma abreviação. Formalmente, as variáveis em Perl são marcadas com os operadores &quot;${}&quot;, &quot;@{}&quot;, e &quot;%{}&quot;. Assim, a forma &quot;longa&quot; da sintaxe correta de Perl para dizer &quot;$lista&quot;, na verdade, é &quot;${lista}&quot;.<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 &quot;nome&quot;. Em perl, para fazer isso, podemos usar strings ou expressões. Por exemplo:<br>

<br>
$nome = &#39;lista&#39;;<br>
${ $nome } = [ 1, 2, 3, 4, 5 ]; # mesma coisa que &quot;$lista = ...&quot;<br>
<br>
$counter = 1;<br>
${ &#39;nome&#39; . $counter } = &#39;valor&#39;; # mesmo que &quot;$nome1 = &#39;valor&#39;;&quot;<br>
<br>
Assim, todas as variáveis em Perl tem duas partes distintas: um &quot;container&quot;, que indica o tipo de variável, e um &quot;nome&quot;, 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 &quot;nome&quot; 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>
@{ &nbsp;${ lista } &nbsp;} = ( 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 &quot;12345&quot;<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 &quot;()&quot; no nome da função, ou o Perl ficaria muito confuso e sem saber se o nome que está dentro do container &quot;@{}&quot; é 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 &quot;&amp;{}&quot;. ATENÇÃO: por diversas razões, ao longo do desenvolvimento da linguagem, a gente parou de escrever &quot;&amp;funcao( $argumento )&quot; e passou a usar a forma mais flexível &quot;funcao( $argumento )&quot;. Assim, usamos o símbolo &quot;&amp;{}&quot; apenas para falar sobre a entrada na tabela de símbolos correspondente àquela subrotina. Por exemplo:<br>

<br>
sub faz_coisas { return &quot;feito&quot;; }<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 = \ &amp;{ faz_coisas };<br>
<br>
Note que eu usei uma &quot;bareword&quot; para indicar o nome da função, o que é perfeitamente válido. Poderia ter escrito também<br>
<br>
$ref_faz_coisas = \ &amp;{ &#39;faz_coisas&#39; };</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 (&#39;\&#39;) 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 &quot;&amp;{ faz_coisas }&quot; ou &quot;&amp;{ &#39;faz_coisas&#39; }&quot; sem mencionar o operador de referência faz o perl buscar o valor de &#39;faz_coisas&#39; 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 &quot;referência de verdade&quot; para uma função. Exemplo:<br>

<br>
# com um nome e /lookup/:<br>
&amp;{ &#39;faz_coisas&#39; }( &#39;argumento1&#39;, &#39;argumento2&#39; );<br>
<br>
# ou, com uma referência de verdade:<br>
$ref = \ &amp;faz_coisas; # criando referencia com o operador &#39;\&#39;<br>
$ref-&gt;( &#39;argumento1&#39;, &#39;argumento2&#39; ); # 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 &quot;Como Perl faz isso ?!&quot;. <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>[]&#39;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 &quot;\x54\x68\x65\x20\x53\x69\x6c\x65\x6e\x74\x20\x47\x75\x61\x72\x64\x69\x61\x6e&quot;,$/<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>