:TITLE: Variações em argumentos de procs e valores de retorno
;#
;# RCSID: $Header: /home/clif/CVS_ROOT/TclTutor/Tcl12.lsn,v 1.8 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: 03/01/2006
;#*********************************************************
:LESSON_TEXT_START_LEVEL 0:
Um proc pode ser definido com um conjunto específico de argumentos
requeridos (como foi feito com <CODE>sum</CODE> na lição anterior)
ou pode ter um número variável de argumentos. Um argumento pode
também ser definido para ter um valor padrão.
<P>
Variáveis podem ser definidas com um valor padrão colocando o nome
da variável e o padrão dentro de chaves. Veja o código do exemplo
para ver como isso é feito.
<P>
Um proc aceitará um número variável de argumentos se o último argumento
declarado for a palavra <B>args</B>. Se o último argumento para uma lista
de argumentos proc for <B>args</B>, então quaisquer argumentos que ainda
não foram atribuídos às variáveis anteriores serão atribuídos a <B>args</B>. 
<P>
<B>Exemplo</B> é definido com três argumentos. Ao menos um argumento
*deve* estar presente quando <B>exemplo</B> for chamado. O segundo argumento
pode ser deixado de fora, e nesse caso ele será padronizado para uma
string vazia. A declaração de <B>args</B> como o último argumento
de <B>exemplo</B> permite que o proc tenha um número variável de
argumentos.
<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 seus argumentos para a chamada do programa. Se não houver 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:
Um proc pode ser definido com um conjunto específico de argumentos 
requeridos (como foi feito com <CODE>sum</CODE> na lição anterior) ou
pode ter um número variável de argumentos. Um argumento pode também
ser definido para ter um valor padrão.
<P>
Variáveis podem ser definidas com um valor padrão colocando o
nome da variável e o padrão dentro de chaves. Veja o código do
exemplo para ver como isso é feito.
<P>
Um proc irá aceitar um número variável de argumentos se o último
argumento declarado for a palavra <B>args</B>. Se o último argumento
para uma lista de argumentos de um proc for <B>args</B>, então quaisquer
argumentos que não foram atribuídos ainda às variáveis anteriores serão
atribuídos a <B>args</B>. 
<P>
<B>Exemplo</B> é definido com três argumentos. Ao menos um argumento
*deve* estar presente quando <B>exemplo</B> for chamado. O segundo argumento
pode ser deixado de fora, e nesse caso ele será padronizado para uma
string vazia. A declaração de <B>args</B> como o último argumento
de <B>exemplo</B> permite que o proc tenha um número variável de
argumentos.
<P>
Note que se há uma outra variável que não <B>args</B> depois de uma
variável com um padrão, então o padrão nunca será usado.
Por exemplo, se você declara um proc como:
<P><CODE>proc funcao { a {b 1} c } {...}</CODE><P>
Tcl atribui valores para as variáveis de um proc na ordem que elas são
listadas no comando. Se você fornece 2 argumentos quando você chama 
<CODE>funcao</CODE> eles serão atribuídos a <CODE>a</CODE> e <CODE>b</CODE>, 
e Tcl irá gerar um erro porque <CODE>c</CODE> não foi definida.
<P>
Você pode, todavia, declarar outros argumentos que podem não ter
valores a eles atribuídos, mas que tenham um valor padrão. Por
exemplo, isso é válido:
<P> <CODE> proc exemplo {requerido {padrao1 a} {padrao2 b} args} {...}
</CODE>
<P>
Neste caso, <CODE>exemplo</CODE> requer um argumento, que será atribuído
à variável <CODE>requerido</CODE>. Se houver dois argumentos, o segundo
argumento será atribuído a <CODE>padrao1</CODE>. Se houver 3 argumentos,
o primeiro será atribuído a <CODE>requerido</CODE>, o segundo a
<CODE>padrao1</CODE>, e o terceiro a <CODE>padrao2</CODE>.
Se <I>exemplo</I> for chamado com mais de 3 argumentos, todos os
argumentos depois do terceiro serão atribuídos a <CODE>args</CODE>.

:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
Um proc pode ser definido com um conjunto específico de argumentos 
requeridos (como foi feito com <CODE>sum</CODE> na lição anterior) ou
pode ter um número variável de argumentos. Um argumento pode também
ser definido para ter um valor padrão.
<P>
A variável declarada em <I>args</I> pode também ser uma lista.
Isso é feito delimitando duas strings dentro de chaves. Quando
o interpretador Tcl encontra essa construção, ele declara
o nome da variável para ser a primeira string, e o valor padrão
para ser a segunda string. Se o proc for chamado sem um
argumento naquela posição, então o valor padrão será atribuído
à variável.
<P>
Um proc irá aceitar um número variável de argumentos se o último
argumento declarado for a palavra <B>args</B>. Se o último argumento
para uma lista de argumentos de um proc for <B>args</B>, então quaisquer
argumentos que não foram atribuídos ainda às variáveis anteriores serão
atribuídos a <B>args</B>. 
<P>
<B>Exemplo</B> é definido com três argumentos. Ao menos um argumento
*deve* estar presente quando <B>exemplo</B> for chamado. O segundo argumento
pode ser deixado de fora, e nesse caso ele será padronizado para uma
string vazia. A declaração de <B>args</B> como o último argumento
de <B>exemplo</B> permite que o proc tenha um número variável de
argumentos.
<P>
Note que se há uma outra variável que não <B>args</B> depois de uma
variável com um padrão, então o padrão nunca será usado.
Por exemplo, se você declara um proc como:
<P><CODE>proc funcao { a {b 1} c } {...}</CODE><P>
Tcl atribui valores para as variáveis de um proc na ordem que elas são
listadas no comando. Se você fornece 2 argumentos quando você chama 
<CODE>funcao</CODE> eles serão atribuídos a <CODE>a</CODE> e <CODE>b</CODE>, 
e Tcl irá gerar um erro porque <CODE>c</CODE> não foi definida.
<P>
Você pode, todavia, declarar outros argumentos que podem não ter
valores a eles atribuídos, mas que tenham um valor padrão. Por
exemplo, isso é válido:
<P> <CODE> proc exemplo {requerido {padrao1 a} {padrao2 b} args} {...}
</CODE>
<P>
Neste caso, <CODE>exemplo</CODE> requer um argumento, que será atribuído
à variável <CODE>requerido</CODE>. Se houver dois argumentos, o segundo
argumento será atribuído a <CODE>padrao1</CODE>. Se houver 3 argumentos,
o primeiro será atribuído a <CODE>requerido</CODE>, o segundo a
<CODE>padrao1</CODE>, e o terceiro a <CODE>padrao2</CODE>.
Se <I>exemplo</I> for chamado com mais de 3 argumentos, todos os
argumentos depois do terceiro serão atribuídos a <CODE>args</CODE>.
<P>
Como você observa no exemplo, com <B>args</B> como o último argumento,
<CODE>exemplo</CODE> pode ser chamado com um, dois, três ou mais argumentos.
Se você chamar <CODE>exemplo</CODE> com um argumento, então é 
atribuído o valor padrão ao <B>segundo</B> argumento, e <B>args</B> será
uma string vazia. Quando <CODE>exemplo</CODE> é chamado com dois argumentos
então <B>primeiro</B> irá conter o primeiro argumento, <B>segundo</B>
irá conter o segundo argumento, e <B>args</B> é ainda uma lista vazia.
Se há mais de dois argumentos, então o terceiro, ou n-ésimo argumentos,
serão atribuídos a <B>args</B>.
:TEXT_END:

:CODE_START:
proc exemplo {primeiro {segundo ""} args} {
  if {$segundo == ""} {
    puts "Há apenas um argumento e ele é: $primeiro"
    return 1
    } else {
    if {$args == ""} {
      puts "Há dois argumentos - $primeiro e $segundo"
      return 2
      } else {
      puts "Há muitos argumentos - $primeiro, $segundo e $args"
      return muitos
      }
    }
  }

set cont1 [exemplo UM]
set cont2 [exemplo UM DOIS]
set cont3 [exemplo UM DOIS TRES]
set cont4 [exemplo UM DOIS TRES QUATRO]

puts "O exemplo foi chamado com $cont1, $cont2, $cont3 e $cont4 argumentos"
:TEXT_END:

