:TITLE: Adição de novos comandos a Tcl - proc
;#
;# RCSID: $Header: /home/clif/CVS_ROOT/TclTutor/Tcl11.lsn,v 1.7 2000/04/24 16:17:50 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: 30/12/2005
;#*********************************************************
:LESSON_TEXT_START_LEVEL 0:
Em Tcl, não há atualmente distinção entre funções e comandos.
Não há palavras reservadas como existe em C, BASIC, FORTRAN, etc. Quando
o interpretador Tcl inicia, há uma lista de funções conhecidas na
tabela que o interpretador utiliza para tratar uma linha. Existem os
comandos que Tcl conhece por padrão. Esses comandos incluem 
<CODE>while,for, set, puts,</CODE> etc. 
<P>
O comando <CODE>proc</CODE> adiciona um novo procedimento à lista
de comandos conhecidos. A sintaxe para o comando <CODE>proc</CODE> é:
<P><B>proc</B> <I>nome args corpo</I>
<P>
Quando <CODE>proc</CODE> é chamado, ele cria uma estrutura para definir
o procedimento, e adiciona aquela estrutura e <I>nome</I> para as tabelas
usadas no tratamento de comandos. Se o comando já existe, então ele
será substituído pelo novo comando com o mesmo nome.
<P>
<I>Args</I> é uma lista de argumentos que será passada para <I>nome</I>. Quando
<I>nome</I> é chamado, variáveis locais com esses nomes serão criadas,
e os valores a serem passado para <I>nome</I> serão copiados para as variáveis locais.
<P>
<I>Corpo</I> é um corpo de código para executar quando <I>nome</I> for chamado.
<P>
O valor que o <I>corpo</I> de um proc retorna pode ser definido com
o comando <CODE>return</CODE>. O comando <CODE>return</CODE> irá retornar seu
argumento para a chamada do programa. Se não há um retorno, então o <I>corpo</I>
irá retornar para quem chamou o proc quando a última chave de fechamento
for alcançada, e o proc irá retornar o valor do último comando a ser executado.
:TEXT_END:
:LESSON_TEXT_START_LEVEL 1:
Em Tcl, não há atualmente distinção entre funções e comandos.
Não há palavras reservadas como existe em C, BASIC, FORTRAN, etc. Quando
o interpretador Tcl inicia, há uma lista de funções conhecidas na
tabela que o interpretador utiliza para tratar uma linha. Existem os
comandos que Tcl conhece por padrão. Esses comandos incluem 
<CODE>while,for, set, puts,</CODE> etc. 
<P>
O comando <CODE>proc</CODE> adiciona um novo procedimento à lista
de comandos conhecidos. A sintaxe para o comando <CODE>proc</CODE> é:
<P><B>proc</B> <I>nome args corpo</I>
<P>
Quando <CODE>proc</CODE> é chamado, ele cria uma estrutura para definir
o procedimento, e adiciona aquela estrutura e <I>nome</I> para as tabelas
usadas no tratamento de comandos. Se o comando já existe, então ele
será substituído pelo novo comando com o mesmo nome.
<P>
<I>Args</I> é uma lista de argumentos que será passada para <I>nome</I>. Quando
<I>nome</I> é chamado, variáveis locais com esses nomes serão criadas,
e os valores a serem passado para <I>nome</I> serão copiados para as variáveis locais.
<P>
<I>Corpo</I> é um corpo de código para executar quando <I>nome</I> for chamado.
<P>
O valor que o <I>corpo</I> de um proc retorna pode ser definido com
o comando <CODE>return</CODE>. O comando <CODE>return</CODE> irá retornar seu
argumento para a chamada do programa. Se não há um retorno, então o <I>corpo</I>
irá retornar para quem chamou o proc quando a última chave de fechamento
for alcançada, e o proc irá retornar o valor do último comando a ser executado.
:TEXT_END:
:LESSON_TEXT_START_LEVEL 2:
Na maioria das linguagens de programação há um conjunto de comandos
internos que o compilador conhece, e um conjunto de funções que um usuário
escreve como parte de seu programa. Os comandos que o compilador conhece são
codificados internamente no compilador, e você não pode usar essas palavras
para outra coisa que não o que foi intencionado para elas. O código para
implementar esses comandos pode ser adicionado como chamadas de função
ou como um montador de código em tempo de execução. O código para
as funções do usuário são sempre adicionadas como chamadas de função.
<P>
Em Tcl não há distinção entre funções e comandos. Não há palavras
reservadas como as que existem em C, BASIC, FORTRAN, etc. Quando
o interpretador Tcl é carregado, há uma lista de funções conhecidas
na tabela que o interpretador utiliza para tratar uma linha. Há os
comandos que Tcl conhece por padrão. Esses comandos incluem <CODE>while,
for, set, puts,</CODE> etc. 
<P>
O comando <CODE>proc</CODE> adiciona um novo procedimento à lista de
comandos conhecidos. A sintaxe para o comando <CODE>proc</CODE> é:
<P><B>proc</B> <I>nome args corpo</I>
<P>
Quando <CODE>proc</CODE> é chamado, ele cria uma estrutura para definir
o procedimento, e adiciona aquela estrutura e <I>nome</I> às tabelas
usadas quando os comandos são tratados. Se o comando já existe, então
ele será substituído pelo novo comando com o mesmo nome.
<P>
<I>Args</I> é uma lista de argumento que será passado para <I>nome</I>. 
Quando <I>nome</I> é chamado, variáveis locais com esses nomes serão
criadas, e os valores a serem passados para <I>nome</I> serão copiados
para as variáveis locais.
<P>
<I>Corpo</I> é um corpo de código para executar quando <I>nome</I> for chamado.
<P>
O valor que o <I>corpo</I> de um procedimento retorna pode ser definido com o
comando <CODE>return</CODE>. O comando <CODE>return</CODE> irá retornar seu
argumento para a chamada do programa. Se não há retorno, então o <I>corpo</I>
irá retornar para quem chamou o proc quando a última chave de fechamento for
alcançada, e o proc irá retornar o valor do último comando a ser executado.
<P>
<B>Dica para o estilo de programação</B>
<P>
Use procs. Use-os freqüentemente. Um programa Tcl (ou qualquer outro programa)
deveria consistir de um conjunto muito pequeno de tarefas na rotina principal,
e a maioria do processamento deveria ser feita em procs. Se você elaborar bem
seus procs, você será capaz de extrai-los mais tarde e utilizá-los em uma
parte diferente do código, sem reescrevê-los. Tende a ser mais difícil
recolher partes e movê-las da linha de código principal. Você acaba aprendendo
subitamente que uma variável foi inicializada muitas centenas de linhas antes,
ou alguma outra coisa desagradável.
<P>
Dividir o código em procs também torna cada módulo individual menor. O
módulo menor é aquele onde menos interações são feitas, e onde um
número menor dessas interações irão "morder você". Módulos menores
são também mais fáceis de compreender e mais seguros de modificar.
<P>
Desde que Tcl é uma linguagem ideal para um estilo de desenvolvimento de
rápido protótipo, as singularidades são tão boas que, à medida que o projeto
progride, você irá mudar o comportamento dos procs, normalmente adicionando
mais fuincionalidades a eles. Se você iniciá-los muito pequenos, eles
terão um tamanho médio ao final. Se você iniciá-los muito grandes, eles
irão terminar maiores ainda e não irão exercer a funcionalidade adequada.
<P>
Elabore procs com a idéia de que eles serão usados em qualquer lugar,
e serão modificados a todo momento. Se isso não acontecer, você ficará
emperrado com procs bem elaborados. Se, ao contrário, isso acontecer,
você ficará feliz em colocar esforço extra em fazer bem a tarefa da
primeira vez.
<P>
O fato de um proc retornar o valor de retorno do último comando
executado, por padrão, pode ser usado para evitar que
você digite muitos caracteres. Não se deixe levar por essa tentação.
Se você tem a intenção de fazer uso de procs para retornar um valor,
então indique isso explicitamente. Caso contrário, você fará
uma mudança 'inofensiva' em algum ponto adiante, sem intenção de
mudar o retorno, e irá travar o seu código em uma desagradável e
difícil forma de entender.
:TEXT_END:

:CODE_START:
proc soma {arg1 arg2} {
  set x [expr $arg1+$arg2];
  return $x
  }

puts "The soma de 2 + 3 é: [soma 2 3]\n\n"

proc for {a b c} {
	puts "O comando for foi substituído por um puts"
	puts "Os argumentos eram: $a\n$b\n$c\n"
	}

for {set i 1} {$i < 10} {incr i}
:TEXT_END: