:TITLE: Vetores Associativos
;#
;# RCSID: $Header: /home/cvs/TclTutor3/lesson/Tcl_Portuguese/Tcl_Portuguese22.lsn,v 1.1 2008/08/02 12:37:36 clif Exp $
;# Copyright (c) 1995 Clif Flynt
;# 9300 Fleming Rd.
;# Dexter, MI  48130
;# clif@cflynt.com
;# Veja o arquivo "AVISO" com os termos da licença.
;#
;#*********************************************************
;# Portuguese translation: Lucio Agostinho Rocha
;# E-mail: outrosdiasvirao@yahoo.com.br
;# Last update: 09/01/2006
;#*********************************************************
:LESSON_TEXT_START_LEVEL 0:
Como AWK e Perl, Tcl suporta vetores associativos.
<P>
A sintaxe para um vetor associativo é colocar o índice dentro de
parênteses.
<P>
Há muitos comandos de vetor além dos que simplesmente acessam e
criam vetores. Esses comandos serão discutidos nesta e na próxima lição.
<DL>
<B><DT>array exists</B> <I>nomeVetor</I>
<DD> Returna 1 se <I>nomeVetor</I> é uma variável vetor. Returna 0
se <I>nomeVetor</I> é uma variável escalar, proc, ou não existe.
<B><DT>array names</B> <I>nomeVetor</I> <I>?modelo?</I>
<DD>Retorna uma lista dos índices para o vetor associativo <I>nomeVetor</I>.
Se <I>modelo</I> é fornecido, apenas aqueles índices que são compatíveis com
o <I>modelo</I> são retornados. A busca é feita utilizando a técnica 
<I>globbing</I> de <CODE>string match</CODE>.
<B><DT>array size</B> <I>nomeVetor</I>
<DD>Retorna o número de elementos do vetor <I>nomeVetor</I>.
<B><DT>array get</B> <I>nomeVetor</I>
<DD>Retorna uma lista na qual cada membro ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo. O elemento da lista seguinte a ele é
o valor daquele membro do vetor.
<B><DT>array set</B> <I>nomeVetor listaDados</I>
<DD>Converte uma lista em um vetor associativo.
<I>listaDados</I> é uma lista no formato daquele que é retornado por
<CODE>array get</CODE>. Cada elemento ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo, e o elemento da lista seguinte a ele
é o valor daquele membro do vetor.
</DL>
<P>
Quando um nome de vetor associativo é dado como argumento para
o comando <CODE>global</CODE>, todos os elementos do vetor associativo
se tornam disponíveis para aquele proc. Por essa razão, 
<I>Brent Welch</I> recomenda (em <I>Practical Programming in Tcl and Tk</I>) 
utilizar um vetor associativo para declarar uma estrutura em um pacote.

:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Linguagens como C, BASIC e FORTRAN suportam vetores nos quais o valor do
índice é um inteiro. Tcl, como AWK e Perl, suporta vetores associativos nos
quais o valor do índice é uma string.
<P>
A sintaxe para um vetor associativo é colocar o índice dentro de
parênteses.
<P>
Há muitos comandos de vetor além dos que simplesmente acessam e
criam vetores. Esses comandos serão discutidos nesta e na próxima lição.
<DL>
<B><DT>array exists</B> <I>nomeVetor</I>
<DD> Returna 1 se <I>nomeVetor</I> é uma variável vetor. Returna 0
se <I>nomeVetor</I> é uma variável escalar, proc, ou não existe.
<B><DT>array names</B> <I>nomeVetor</I> <I>?modelo?</I>
<DD>Retorna uma lista dos índices para o vetor associativo <I>nomeVetor</I>.
Se <I>modelo</I> é fornecido, apenas aqueles índices que são compatíveis com
o <I>modelo</I> são retornados. A busca é feita utilizando a técnica 
<I>globbing</I> de <CODE>string match</CODE>.
<B><DT>array size</B> <I>nomeVetor</I>
<DD>Retorna o número de elementos do vetor <I>nomeVetor</I>.
<B><DT>array get</B> <I>nomeVetor</I>
<DD>Retorna uma lista na qual cada membro ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo. O elemento da lista seguinte a ele é
o valor daquele membro do vetor.
<B><DT>array set</B> <I>nomeVetor listaDados</I>
<DD>Converte uma lista em um vetor associativo.
<I>listaDados</I> é uma lista no formato daquele que é retornado por
<CODE>array get</CODE>. Cada elemento ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo, e o elemento da lista seguinte a ele
é o valor daquele membro do vetor.
</DL>
<P>
Quando um nome de vetor associativo é dado como argumento para
o comando <CODE>global</CODE>, todos os elementos do vetor associativo
se tornam disponíveis para aquele proc. Por essa razão, 
<I>Brent Welch</I> recomenda (em <I>Practical Programming in Tcl and Tk</I>) 
utilizar um vetor associativo para declarar uma estrutura em um pacote.
<P>
Este método torna mais simples compartilhar dados entre muitos procs
que estão trabalhando juntos, e não polui o espaço global de nomes
como precariamente seria feito se fossem utilizados globais para
todos os itens de dados compartilhados.

:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
Há três tipos de estruturas de dados simples em Tcl: a lista, a string e
os vetores associativos. Um vetor associativo é uma coleção de elementos
de dados similar à lista. Em uma lista, todo elemento tem uma localização,
e você pode acessar um elemento de dados através de sua localização (com
o comando <CODE>lindex</CODE>).
Com vetores associativos, cada elemento de dados tem um nome assim como um
valor, e você pode acessar um elemento particular por seu nome.
<P>
Um item em um vetor associativo é descrito por uma string neste formato:
<CODE>nomeVetor(nomeElemento)</CODE>. Assim como variáveis regulares, você
pode atribuir o valor de um elemento no vetor com um comando como:
<PRE><CODE>
set tarefa(Domingo) "Lavar o carro"
set tarefa(Segunda) "Pôr o lixo pra fora"
set tarefa(Quinta) [list {Limpar geladeira} {Ir para o shopping} {Ligar para mamãe}]
</CODE></PRE>
Há muitos comandos de vetor além dos que simplesmente acessam e criam
vetores os quais serão discutidos nesta e na próxima lição.
<DL>
<B><DT>array exists</B> <I>nomeVetor</I>
<DD> Returna 1 se <I>nomeVetor</I> é uma variável vetor. Returna 0
se <I>nomeVetor</I> é uma variável escalar, proc, ou não existe.
<B><DT>array names</B> <I>nomeVetor</I> <I>?modelo?</I>
<DD>Retorna uma lista dos índices para o vetor associativo <I>nomeVetor</I>.
Se <I>modelo</I> é fornecido, apenas aqueles índices que são compatíveis com
o <I>modelo</I> são retornados. A busca é feita utilizando a técnica 
<I>globbing</I> de <CODE>string match</CODE>.
<B><DT>array size</B> <I>nomeVetor</I>
<DD>Retorna o número de elementos do vetor <I>nomeVetor</I>.
<B><DT>array get</B> <I>nomeVetor</I>
<DD>Retorna uma lista na qual cada membro ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo. O elemento da lista seguinte a ele é
o valor daquele membro do vetor.
<B><DT>array set</B> <I>nomeVetor listaDados</I>
<DD>Converte uma lista em um vetor associativo.
<I>listaDados</I> é uma lista no formato daquele que é retornado por
<I>array get</I>. Cada elemento ímpar da lista (1, 3, 5, etc) é
um índice no vetor associativo, e o elemento da lista seguinte a ele
é o valor daquele membro do vetor.
</DL>
<P>
Quando um nome de vetor associativo é dado como argumento para
o comando <CODE>global</CODE>, todos os elementos do vetor associativo
se tornam disponíveis para aquele proc. Por essa razão, 
<I>Brent Welch</I> recomenda (em <I>Practical Programming in Tcl and Tk</I>)
utilizar um vetor associativo para declarar uma estrutura em um pacote.
<P>
Este método torna mais simples compartilhar dados entre muitos procs
que estão trabalhando juntos, e não polui o espaço global de nomes
como precariamente seria feito se fossem utilizados globais para
todos os itens de dados compartilhados.
<P>
Por exemplo, considere um programa que tem muitos procs para
manipular diferentes cálculos, um dos quais tem um subtotal que
tem de ser levado de proc a proc, e todos utilizam o mesmo total.
Você poderia manipular isso dessa forma:

<PRE><CODE>
proc proc1 {} {
  global subtotal1, total;
  ...
  }

proc proc2 {} {
  global subtotal2, total;
  ...
  }
...
</CODE></PRE>
ou dessa forma:
<PRE><CODE>
proc proc1 {} {
  global dados
  set dados(subtotal1) ...
  }

proc proc2 {} {
  global dados
  set dados(subtotal2) ...
  }
...
</CODE></PRE>
No segundo método, há apenas um nome de variável global criado. Isso
dá a você muito menos chance de colidir com outras variáveis globais quando
você juntar o seu conjunto de procs com código de outras pessoas para
criar novos programas.
<P>
Utilizando um vetor associativo também torna mais fácil adicionar um novo
campo, se isso se fizer necessário. Você pode simplesmente adicionar o
novo elemento de dados no vetor associativo, e o elemento se tornará
disponível para quaisquer procs que precisem acessá-lo.
<P>
Um considerável bug comum em programas Tcl é não colocar um comando 
<CODE>global</CODE> para uma variável global. Se isso acontecer, Tcl
irá silenciosamente criar uma variável local com o mesmo nome da 
variável global, e irá utilizá-la naquele proc, mas quaisquer mudanças
que você fizer naquela variável não irão ser refletidas no escopo
global, e o estado atual da variável global não irá estar disponível no
proc. Isso cria um código que é sintaticamente correto, mas não produz os
resultados esperados.
:TEXT_END:

:CODE_START:
array set vetor1 [list {123} {Cassimiro de Abreu} \
		       {234} {José de Alencar} \
		       {345} {Ruty Rocha} \
		       {456} {Machado de Assis} ]

puts "Vetor1 tem [array size vetor1] entradas\n"

puts "Vetor1 tem as as seguintes entradas: \n [array names vetor1] \n"

puts "O número de identificação 123 refere-se a $vetor1(123)\n"

if {[array exist vetor1]} {
   puts "vetor1 é um vetor"
   } else {
   puts "vetor1 não é um vetor"
   }

if {[array exist vetor2]} {
   puts "vetor2 é um vetor"
   } else {
   puts "vetor2 não é um vetor"
   }

:TEXT_END:

