:TITLE: Construindo Bibliotecas de procs - unknown, info library
;#
;# RCSID: $Header: /home/clif/CVS_ROOT/TclTutor/Tcl31.lsn,v 1.6 2000/04/24 16:17:52 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: 16/01/2006
;#*********************************************************
::CMD:: if {([info exists tcl_platform])} {
  switch $tcl_platform(platform) {
    unix        {
                set Tutor(lsn.codeMod) {
                }
        }
    windows     {
                set Tutor(lsn.codeMod) {
		    {regsub {cat} $line {command.com /C type} line}          
                    {if {[glob -nocomplain C:/temp] != ""} {
                      regsub "/tmp" $line {C:/temp} line                      
		    }
		    }
                    {if {[glob -nocomplain C:/windows/temp] != ""} {
                      regsub "/tmp" $line {C:/windows/temp} line
		    }
		    }
                    {if {[glob -nocomplain C:/winnt/temp] != ""} {
                      regsub "/tmp" $line {C:/winnt/temp} line
		    }
		    }
                }         
        }
    mac         {
                set Tutor(lsn.codeMod) {
		}
                }
    default     {
                puts "I don't recognize the platform: $tcl_platform(platform)"
                puts "Can't set platform specific parameters"
                }
    } 
  }

:LESSON_TEXT_START_LEVEL 0:
Tcl fornece uma facilidade para automaticamente carregar procs
quando eles são acessados pela primeira vez, ao invés de carregá-los
com o comando <CODE>source</CODE> quando a aplicação inicia.
Isso pode diminuir o tempo de início de uma aplicação, e mesmo diminuir
o uso da memória se nem todos os procs forem acessados durante
o uso da aplicação.
<P>
O mecanismo para este processo é colocar os arquivos em
um diretório incluido na lista de diretórios <B>auto_path</B>. Cada
um desses diretórios precisa de um índice que é criado pelo comando
<B>auto_mkindex</B>. Quando um proc não reconhecido é chamado, ele
gera uma chamada ao proc <B>unknown</B>, que procura nos arquivos de
índice na lista de diretórios até ele encontrar um proc compatível para o
proc desconhecido (<I>unknown</I>). Quando um proc é encontrado, o
proc <B>unknown</B> automaticamente carrega aquele arquivo, e avalia o
proc, retornando o controle para o script original como se todos os
procs estivessem lá.
<DL>
<B><DT>auto_mkindex</B> <I>dirBiblioteca arquivo1 ... arquivon</I>
<DD>Cria um arquivo de índice (tclIndex) em <I>dirBiblioteca</I> 
a partir dos módulos de código fonte listados como <I>arquivo1 - arquivon</I>. 
Cada proc nos arquivos será listado no arquivo de índice, com uma referência
para o módulo do código fonte que o contém.
<P>
Os descritores de arquivo podem ser qualquer número de strings
usando o mesmo formato dos argumentos para o comando <B>glob</B>.
<P>
Este proc é definido em <B>init.tcl</B> que é carregado do diretório
de biblioteca padrão quando o <I>Tcl shell</I> é inicializado.
<B><DT>info library</B>
<DD>Retorna o nome do diretório de biblioteca no qual os scripts
Tcl padrões são armazenados.
<P>
Procs Tcl que estão em arquivos no diretório de biblioteca Tcl são
carregados automaticamente quando eles são executados.
<P>
Tcl espera encontrar o arquivo <I>init.tcl</I> na localização 
de biblioteca padrão definida quando o interpretador Tcl é construído.
Este caminho pode ser alterado mudando a variável de ambiente
TCL_LIBRARY.
<B><DT>unknown</B> <I>args</I>
<DD>Este proc é chamado pelo interpretador quando ele encontra um
comando que pode ser tratado, mas o nome do comando não está nas
tabelas. <I>Unknown</I> tenta seguir os passos para executar o
comando:
<UL COMPACT>
<LI> Verifica o índice nos diretórios listados em <I>auto_path</I> para ver
se o proc existe em um arquivo. Se o proc é encontrado, o script é carregado
com o proc <B>auto_load</B>, e o proc é executado.
<LI>Se o interpretador está executando interativamente, Tcl tenta <B>executar</B>
o comando com o proc <B>auto_exec</B>.
<LI>Se o comando é um prefixo único para um comando Tcl, <B>unknown</B>
completa o nome do comando, e executa aquele comando.
</UL>
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 1:
Quando um script Tcl inicia sua execução, você pode imediatamente
carregar todos os arquivos que você pode precisar acessar durante a
execução do script, ou você pode esperar até que os procs sejam
chamados e carregar os arquivos neste momento.
<P>
Tcl fornece uma facilidade para automaticamente carregar procs quando
eles são acessados pela primeira vez, ao invés de carregá-los quando
a aplicação inicia. Atrasar as chamadas para carregar os arquivos pode
diminuir o tempo de início da aplicação, e mesmo diminuir o uso da 
memória se nem todos os procs forem acessados durante o uso da
aplicação.
<P>
O procedimento para seguir, para permitir ao Tcl automaticamente carregar 
arquivos, é este:
<OL COMPACT>
<LI>Coloque os arquivos fonte em um único diretório;
<LI>Crie um arquivo de índice (tclIndex) naquele diretório usando <B>auto_mkindex</B>;
<LI>Adicione o caminho desse diretório à lista de diretórios a serem
procurados, <B>lappending</B> a variável global <B>auto_path</B> no script de sua
aplicação.
</OL>
<P>
Quando um proc não reconhecido é chamado, ele
gera uma chamada ao proc <B>unknown</B>, que procura nos arquivos de
índice na lista de diretórios até ele encontrar um proc compatível com o
proc desconhecido (<I>unknown</I>). Quando um proc é encontrado, o
proc <B>unknown</B> automaticamente carrega aquele arquivo, e avalia o
proc, retornando o controle para o script original como se todos os
procs estivessem lá.
<DL>
<B><DT>auto_mkindex</B> <I>dirBiblioteca arquivo1 ... arquivon</I>
<DD>Cria um arquivo de índice (tclIndex) em <I>dirBiblioteca</I> 
a partir dos módulos de código fonte listados como <I>arquivo1 - arquivon</I>. 
Cada proc nos arquivos será listado no arquivo de índice, com uma referência
para o módulo do código fonte que o contém.
<P>
Os descritores de arquivo podem ser qualquer número de strings
usando o mesmo formato dos argumentos para o comando <B>glob</B>.
<P>
Este proc é definido em <B>init.tcl</B> que é carregado do diretório
de biblioteca padrão quando o <I>Tcl shell</I> é inicializado.
<B><DT>info library</B>
<DD>Retorna o nome do diretório de biblioteca no qual os scripts
Tcl padrões são armazenados.
<P>
Procs Tcl que estão em arquivos no diretório de biblioteca Tcl são
carregados automaticamente quando eles são executados.
<P>
Tcl espera encontrar o arquivo <I>init.tcl</I> na localização 
de biblioteca padrão definida quando o interpretador Tcl é construído.
Este caminho pode ser alterado mudando a variável de ambiente
TCL_LIBRARY.
<B><DT>unknown</B> <I>args</I>
<DD>Este proc é chamado pelo interpretador quando ele encontra um
comando que pode ser tratado, mas o nome do comando não está nas
tabelas. <I>Unknown</I> tenta seguir os passos para executar o
comando:
<UL COMPACT>
<LI> Verifica o índice nos diretórios listados em <I>auto_path</I> para ver
se o proc existe em um arquivo. Se o proc é encontrado, o script é carregado
com o proc <B>auto_load</B>, e o proc é executado.
<LI>Se o interpretador está executando interativamente, Tcl tenta <B>executar</B>
o comando com o proc <B>auto_exec</B>.
<LI>Se o comando é um prefixo único para um comando Tcl, <B>unknown</B>
completa o nome do comando, e executa aquele comando.
</UL>
</DL>
:TEXT_END:

:LESSON_TEXT_START_LEVEL 2:
Quando um script Tcl inicia sua execução, você pode imediatamente
carregar todos os arquivos que você pode precisar acessar durante a
execução do script, ou você pode esperar até que os procs sejam
chamados e carregar os arquivos neste momento.
<P>
carregar todos os arquivos quando você inicia pela primeira vez uma
aplicação pode fazer com que ela inicie muito lentamente.
<P>
Checar se cada proc existe antes de você chamá-lo, e carregar o arquivo
nesse momento, cria muito código extra, e faz com que sua aplicação
execute mais lentamente.
<P>
Tcl fornece uma facilidade para automaticamente carregar procs quando
eles são acessados pela primeira vez, ao invés de carregá-los quando
a aplicação inicia. Isso permite a você diminuir o tempo de início de 
aplicações sem adicionar qualquer código extra para checar quais procs
foram definidos. carregar módulos apenas quando necessário pode também
reduzir requerimentos de tarefas de memória, uma vez que nem todos os
procs podem ser necessários cada vez que a aplicação executa.
<P>
O procedimento para seguir, para permitir ao Tcl automaticamente carregar 
arquivos, é este:
<OL COMPACT>
<LI>Coloque os arquivos fonte em um único diretório;
<LI>Crie um arquivo de índice (tclIndex) naquele diretório usando <B>auto_mkindex</B>;
<LI>Adicione o caminho desse diretório à lista de diretórios a serem
procurados, <B>lappending</B> a variável global <B>auto_path</B> no script de sua
aplicação.
</OL>
<P>
Quando um proc não reconhecido é chamado, ele
gera uma chamada ao proc <B>unknown</B>, que procura nos arquivos de
índice na lista de diretórios até ele encontrar um proc compatível com o
proc desconhecido (<I>unknown</I>). Quando um proc é encontrado, o
proc <B>unknown</B> automaticamente carrega aquele arquivo, e avalia o
proc, retornando o controle para o script original como se todos os
procs estivessem lá.
<P>
Execute o exemplo, e examine o código e a saída enquanto você lê a
descrição aqui.
<P>
A primeira porção do exemplo apenas cria um arquivo temporário, da
mesma forma que ele foi criado na lição anterior.
<P>
Depois disso, o diretório temporário é adicionado ao fim da lista de
diretórios para pesquisar quando um proc não definido for encontrado.
(nas versões Tcl8.3 e anteriores, essa adição de caminho à
variável <CODE>auto_path</CODE> deve vir depois de <CODE>auto_mkindex</CODE>.)
Então, aquela lista é exibida. Ela, provavelmente, exibe ao menos duas entradas em
sua máquina. As duas primeiras serão os caminhos de bibliotecas onde
os interpretadores Tcl e Tk esperam encontram os arquivos de inicialização.
Depois disso, irá aparecer o diretório temporário, que nós adicionamos.
<P>
A seguir, o diretório de biblioteca padrão do compilador é exibido. Esse
diretório será uma das duas primeiras bibliotecas da saída anterior.
<P>
A próxima linha cria o arquivo de índice. Neste caso, ele define
apenas um arquivo para ser colocado no índice. O segundo argumento
poderia ser <B>*.tcl</B>, o que faria com que todos os arquivos com a
extensão <B>.tcl</B> fossem adicionados ao índice.
<P>
Depois disso, o código confirma que <B>procTeste</B> não foi definido,
e então executa <B>procTeste</B>. A saída mostra que <B>procTeste</B>
não foi definido originalmente, mas pôde ser executado com sucesso.
Depois que <B>procTeste</B> foi chamado, o código confirma que ele
ainda existe.
<P>
Finalmente, os arquivos temporários são apagados.
<DL>
<B><DT>auto_mkindex</B> <I>dirBiblioteca arquivo1 ... arquivon</I>
<DD>Cria um arquivo de índice (tclIndex) em <I>dirBiblioteca</I> 
a partir dos módulos de código fonte listados como <I>arquivo1 - arquivon</I>. 
Cada proc nos arquivos será listado no arquivo de índice, com uma referência
para o módulo do código fonte que o contém.
<P>
Os descritores de arquivo podem ser qualquer número de strings
usando o mesmo formato dos argumentos para o comando <B>glob</B>.
<P>
Este proc é definido em <B>init.tcl</B> que é carregado do diretório
de biblioteca padrão quando o <I>Tcl shell</I> é inicializado.
<B><DT>info library</B>
<DD>Retorna o nome do diretório de biblioteca no qual os scripts
Tcl padrões são armazenados.
<P>
Procs Tcl que estão em arquivos no diretório de biblioteca Tcl são
carregados automaticamente quando eles são executados.
<P>
Tcl espera encontrar o arquivo <I>init.tcl</I> na localização 
de biblioteca padrão definida quando o interpretador Tcl é construído.
Este caminho pode ser alterado mudando a variável de ambiente
TCL_LIBRARY.
<B><DT>unknown</B> <I>args</I>
<DD>Este proc é chamado pelo interpretador quando ele encontra um
comando que pode ser tratado, mas o nome do comando não está nas
tabelas. <I>Unknown</I> tenta seguir os passos para executar o
comando:
<UL COMPACT>
<LI> Verifica o índice nos diretórios listados em <I>auto_path</I> para ver
se o proc existe em um arquivo. Se o proc é encontrado, o script é carregado
com o proc <B>auto_load</B>, e o proc é executado.
<LI>Se o interpretador está executando interativamente, Tcl tenta <B>executar</B>
o comando com o proc <B>auto_exec</B>.
<LI>Se o comando é um prefixo único para um comando Tcl, <B>unknown</B>
completa o nome do comando, e executa aquele comando.
</UL>
</DL>
:TEXT_END:

:CODE_START:
;# Cria um arquivo temporário com um proc de teste

set nomeArquivo /tmp/TT_[pid]
set arquivoSaida [open $nomeArquivo w]

puts $arquivoSaida {set scr [info script]}
puts $arquivoSaida "proc procTeste {} {"
puts $arquivoSaida "global scr"
puts $arquivoSaida "puts \"Arquivo fonte de procTeste: \$scr.\""
puts $arquivoSaida "puts \"procTeste executando de \[info script]\n\""
puts $arquivoSaida "}"

flush $arquivoSaida
close $arquivoSaida

puts "Os diretórios na variável global auto_path são: $auto_path\n"
puts "A biblioteca padrão é: [info library]\n";

auto_mkindex /tmp [file tail $nomeArquivo]

# Nas versões Tcl8.3 e anteriores, isso deve vir depois de auto_mkindex

lappend auto_path /tmp

if { [info procs procTeste] == ""} {
  puts "procTeste não existe\n"
  }

procTeste

if { [info procs procTeste] != ""} {
  puts "\nprocTeste existe agora"
  }

file delete /tmp/tclIndex
file delete $nomeArquivo

:TEXT_END: