[Cascavel-pm] Procurando chifre em cabeça de cavalo ???
Luis Campos de Carvalho
lechamps em terra.com.br
Terça Junho 8 12:26:33 CDT 2004
Solli Moreira Honorio wrote:
> Pessoal,
>
> Eu acabei de ver uma pergunta interessante no Perlmonks e queria
> reproduzir-la. O cara mostrou dois código que de vista ambos deveriam
> funciar, mas não foi o caso, vejam só:
>
> %hash = map { $_, "$var/$_" } @array; # Works great
perl -MData::Dumper -e '$var = "X"; %hash = map { $_, "$var/$_" }
"a".."h"; print Dumper( \%hash ), "\n"; '
$VAR1 = {
'e' => 'X/e',
'a' => 'X/a',
'd' => 'X/d',
'c' => 'X/c',
'h' => 'X/h',
'b' => 'X/b',
'g' => 'X/g',
'f' => 'X/f'
};
> %hash = map { "$var/$_", $_ } @array; # Syntax Error!
perl -MData::Dumper -e '$var = "X"; %hash = %hash = map { "$var/$_",
$_ } "a".."h"; print Dumper( \%hash ), "\n"; '
syntax error at -e line 1, near "} "a""
Execution of -e aborted due to compilation errors.
> A explicação é que '{' pode inicar tanto um hash como um bloco, sendo
> assim a '{' pode ser utilizada tanto para iniciar um bloco como para
> LIST, expressão. Como o Perl não olha a sentença inteira (na verdade eu
> acho que nenhuma linguagem de programação faz, elas compilam do início
> para o final e da esquerda para a direita - linearmente...), o map tem
> que adivinhar o que é desejado. Sendo assim é só utilizar a velha regra
> de matemática de explicitar o que você quer fazer primeiro com '()'.
> (mais informação : perldoc -f map )
Correto! Perfeito!
> A solução para o código com erro de sintaxe é :
Solução? Vamos ver isso mais de perto...
> %hash = map { ( "$var/$_", $_ ) } @array; ou
Reproduzi assim:
perl -MData::Dumper -e '$var = "X"; %h = map { ( "$var/$_", $_ ) }
"a".."h"; print Dumper( \%h ), "\n";'
E obtive:
$VAR1 = {
'X/f' => 'f',
'X/e' => 'e',
'X/b' => 'b',
'X/d' => 'd',
'X/h' => 'h',
'X/c' => 'c',
'X/a' => 'a',
'X/g' => 'g'
};
> %hash = map +{ "$var/$_", $_ } @array;
Notem que aqui existe um erro de sintaxe: deveria haver uma ',' depois
de '}' e antes de '@', na linha acima...
Reproduzi assim:
perl -MData::Dumper -e '$var = "X"; %h = map +{ "$var/$_", $_ },
"a".."h"; print Dumper( \%h ), "\n";'
E obtive:
$VAR1 = {
'HASH(0x81bae74)' => {
'X/d' => 'd'
},
'HASH(0x813eb9c)' => {
'X/h' => 'h'
},
'HASH(0x81baee0)' => {
'X/f' => 'f'
},
'HASH(0x813eab8)' => {
'X/b' => 'b'
}
};
Desnecessário dizer que os códigos produzem coisas diferentes, como
era de se esperar... ;-)
A solução esperada para o problema (que envolve conhecer realmente o
parser do Perl) é acrescentar um '+' antes da string, dentro das chaves,
assim:
perl -MData::Dumper -e '$var = "X"; %hash = %hash = map { +"$var/$_",
$_ } "a".."h"; print Dumper( \%hash ), "\n"; '
$VAR1 = {
'X/f' => 'f',
'X/e' => 'e',
'X/b' => 'b',
'X/d' => 'd',
'X/h' => 'h',
'X/c' => 'c',
'X/g' => 'g',
'X/a' => 'a'
};
Desta forma, você obtém o resultado desejado, usando a sintaxe correta.
> Olhando o problema me lembrei de uma discussão que tivemos em um dos
> 'social meet' sobre a sintaxe do Perl, o Luis (monsieur champs) diz que
> ela é maravilhosa (e nem aceita discutição... é um ditador em pessoa
> :-), mas outros (como eu) acha que ela pode levar a confusão
> (principalmente para o iniciantes), como esta.
Eu realmente dissse que a sintaxe do Perl é maravilhosa. Mas não
aceito que se considere a palavra "maravilhosa" semânticamente
equivalente à palavra "didática": exatamente como os códigos
apresentados pelo Solli, acima, as palavras dizem coisas diferentes, a
pesar de "se parecerem muito"... (notem a ironia carregada ;-)
<funny>
<troll>
Se alguém aqui está procurando uma linguagem "didática",
melhor tentar com pascal... :-P Perl não foi projetada
para ser "didática", mas sim "eclética". Você pode até
ser "didático" em perl, mas apenas por que você quer.
</troll>
</funny>
> Isto só vem enfatizar a máxima do Perl, "Sempre existe mais de uma
> maneira de fazer a mesma coisa".
Perl garante mais de uma forma de fazer a mesma coisa para fazer
coisas iguais de jeitos diferentes... você tentou fazer coisas
diferentes usando jeitos iguais... tem coisa estranha aqui... :-)
Foi divertido!
Vamos conversar mais disso no próximo social meeting?
[]'Z!
--
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Luis Campos de Carvalho is BSc in Comp Science,
PerlMonk [SiteDocClan], Cascavel-pm Moderator,
Unix Sys Admin && Certified Oracle DBA
http://br.geocities.com/monsieur_champs/
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Mais detalhes sobre a lista de discussão Cascavel-pm