Tcl (pronuncia-se ticol, a abreviação de Tool Comand Language) é uma linguagem de script muito útil que roda na maioria das plataformas UNIX e Windows.
Combinada com a biblioteca gráfica Tk (pronuncia-se tikei), a qual fornece os Widgets (elementos gráficos), a Tcl pode ser usada para gerar programas com interfaces gráficas com o usuário.
A biblioteca Tk está para a Tcl assim como AWT e Swing está para o Java.
A biblioteca Tk não é exclusiva da Tcl, mas é possível usá-la também com outras linguagens de script como Perl ou Python.
Tcl é uma linguagem de script dinâmica isto significa que o código fonte que você escreve usando Tcl não é compilado [2] em um arquivo binário que possa ser executado por conta própria. Mas é armazenado como um conjunto de instruções (comandos) escrito em um ou mais arquivos de texto simples, os quais são interpretados no momento da execução pelo interpretador Tcl.
O interpretador Tcl nada mais é do que um programa binário (compilado) que pode compreender e processar os scripts escritos em Tcl.
Para rodar em uma uma plataforma específica (Linux, Windows, Mac etc) é necessário um interpretador para a respectiva plataforma.
Cada interpretador Tcl em execução deve ser considerado como uma máquina virtual separada e com seu próprio estado interno que é, consequentemente, modificado na medida que chegam os comandos.
Os comandos podem ser lidos a partir de um arquivo contendo um script ou pela “entrada padrão” (terminal) permitindo interagir com o interpretador de maneira dinâmica.
A figura seguinte mostra a chamada do interpretador Tcl pelo terminal pelo comando tclsh85 e após o prompt %
a execução do comando info patchlevel.
Figura 76. Chamada do interpretador Tcl em um terminal e a execução de alguns comandos. (Fonte: Tcl 8.5 Networking Programming, 2010)
O comando tclsh85 é usado para refletir a versão instalada do interpretador, mas poderia ser também tclsh, e o comando info patchlevel retorna informações sobre a versão do interpretador instalado e o comando exit encerra a execução do interpretador. (Fonte: Tcl 8.5 Networking Programming, 2010)
Junto com o interpretador tclsh existe outro aplicativo chamado wish, que além de executar os comandos da Tcl também carrega o pacote Tk que permite criar os widgets
A instalação em ambiente Windows é feita com um executável do tipo ActiveTcl8.5.11.0.295402-win32-ix86-threaded.exe
, versão disponível no momento em que escrevo este parágrafo (24/01/2012), na área de downloads da empresa ActiveState.
Depois de baixar e executar o programa , você a tela do instalador semelhante ao mostrado na figura a seguir.
Figura 77. Tela inicial do instalador do interpretador Tcl ActiveTcl em ambiente Windows.(Fonte: Tcl 8.5 Networking Programming, 2010)
Uma das vantagens deste programa é a possibilidade de escolher o diretório de instalação permitindo que você instale na sua área de usuário sem a necessidade de ser administrador da sua máquina. ;^)
Para o Linux você pode baixar o interpretador do site da ActiveState ou os pacotes da sua distribuição além de uma infinidade de pacotes desenvolvidos pela Comunidade de Software Livre.
Por exemplo, para você ter uma idéia das opções de pacotes disponíveis sobre Tcl no Debian 5.0 - Lenny que estou usando, uso o comando:
apt-cache search
tcl
| grep Tcl
Procuro todos os pacotes relacionados com “tcl” e filtro a saída com o comando grep para exibir apenas as linhas onde aparece a string “Tcl” explícita e encontro a seguinte listagem:
libtcl-chiark-1 - Tcl interfaces for adns, cdb, crypto, etc. tclcsound - Tcl bindings and interpreters for Csound gpsmanshp - A Tcl interface to shapelib libgv-tcl - Tcl bindings for graphviz hfsutils-tcltk - Tcl/Tk interfaces for reading and writing Macintosh volumes xhtml2ps - HTML to PostScript converter (Tcl/Tk GUI frontend) tcl8.4-insighttoolkit3 - Image processing toolkit for registration and segmentation - Tcl bindings itcl3.1-dev - [incr Tcl] OOP extension for Tcl 8.3 - development files itcl3.1-doc - [incr Tcl] OOP extension for Tcl 8.3 - manual pages itcl3.1 - [incr Tcl] OOP extension for Tcl 8.3 - run-time files iwidgets3.1-doc - [incr Widgets] OOP extension for Tcl/Tk 8.3 - manual pages iwidgets3.1 - [incr Widgets] OOP extension for Tcl/Tk 8.3 - run-time files itcl3-dev - [incr Tcl] OOP extension for Tcl - development files itcl3-doc - [incr Tcl] OOP extension for Tcl - manual pages itcl3 - [incr Tcl] OOP extension for Tcl - run-time files libtk-img-dev - Extended image format support for Tcl/Tk (development files) libtk-img-doc - Extended image format support for Tcl/Tk (manual pages) libtk-img - Extended image format support for Tcl/Tk (runtime) libmemchan-tcl-dev - Tcl extension for in-memory channels - development files libmemchan-tcl - Tcl extension for in-memory channels - runtime library mysqltcl - Interface to the MySQL database for the Tcl language newt-tcl - A newt module for Tcl pfm - PostgreSQL graphical client using Tcl/Tk libpgtcl-dev - Tcl client library binding for PostgreSQL - development files libpgtcl1.5 - Tcl client library binding for PostgreSQL plplot-tcl-dev - Tcl/Tk development support for PLplot, a plotting library plplot-tcl - Tcl/Tk support for PLplot, a plotting library rrdtool-tcl - Time-series data storage and display system (Tcl interface) libtcltk-ruby - Tcl/Tk interface for Ruby libtcltk-ruby1.8 - Tcl/Tk interface for Ruby 1.8 libtcltk-ruby1.9 - Tcl/Tk interface for Ruby 1.9 sbnc-tcl - an IRC proxy for multiple users (Tcl extension) libsetools-tcl - SETools Tcl bindings libsnack2-alsa - Sound extension to Tcl/Tk and Python/Tkinter - Tcl/Tk library libsnack2-dev - Sound extension to Tcl/Tk and Python/Tkinter - development files libsnack2-doc - Sound extension to Tcl/Tk and Python/Tkinter - documentation libsnack2 - Sound extension to Tcl/Tk and Python/Tkinter - Tcl/Tk library python-tksnack - Sound extension to Tcl/Tk and Python/Tkinter - Python library libsqlite3-tcl - SQLite 3 Tcl bindings libsqlrelay-tcl - SQL Relay Tcl API sufary-tcltk - Tcl/Tk interface for SUFARY tcl8.3-dev - Tcl (the Tool Command Language) v8.3 - development files tcl8.3-doc - Tcl (the Tool Command Language) v8.3 - manual pages tcl8.3 - Tcl (the Tool Command Language) v8.3 - run-time files tcl8.4-dev - Tcl (the Tool Command Language) v8.4 - development files tcl8.4-doc - Tcl (the Tool Command Language) v8.4 - manual pages tcl8.5-dev - Tcl (the Tool Command Language) v8.5 - development files tcl8.5-doc - Tcl (the Tool Command Language) v8.5 - manual pages tcl8.5 - Tcl (the Tool Command Language) v8.5 - run-time files tclcurl - Tcl bindings to libcurl tclex - A lexical analyzer generator for Tcl tclgeoip - Tcl extension implementing GeoIP lookup functions tcllib - the Standard Tcl Library tclodbc - The ODBC extension to Tcl tclreadline - GNU Readline Extension for Tcl/Tk tclthread - Tcl extension implementing script level access to Tcl threading capabilities tk-dev - The Tk toolkit for Tcl and X11 (default version) - development files tk-doc - The Tk toolkit for Tcl and X11 (default version) - manual pages tk - The Tk toolkit for Tcl and X11 (default version) - run-time files tcl-tls - the TLS OpenSSL extension to Tcl libtrf-tcl-dev - Tcl data transformations - development files libtrf-tcl-doc - Tcl data transformations - development files libtrf-tcl - Tcl data transformations - runtime library libudp-tcl - UDP sockets for Tcl tclvfs - Exposes Tcl 8.4's virtual filesystem C API to the Tcl script level tclx8.3-doc - Extended Tcl (TclX) version 8.3.5 -- TclX manpages tclx8.3 - Extended Tcl (TclX) version 8.3.5 -- TclX runtime package tkx8.3-dev - Extended Tcl (TclX) version 8.3.5 -- TkX development package tkx8.3-doc - Extended Tcl (TclX) version 8.3.5 -- TkX manpages tclx8.4-dev - Extended Tcl (TclX) - development package tclx8.4-doc - Extended Tcl (TclX) - manpages tclx8.4 - Extended Tcl (TclX) - shared library tclxml - Tcl library for XML parsing tdom-dev - A fast XML/DOM/XPath/XSLT extension for Tcl written in C - development files tdom - A fast XML/DOM/XPath/XSLT extension for Tcl written in C tk8.3-dev - Tk toolkit for Tcl and X11, v8.3 - development files tk8.3-doc - Tk toolkit for Tcl and X11, v8.3 - manual pages tk8.4-dev - Tk toolkit for Tcl and X11, v8.4 - development files tk8.4-doc - Tk toolkit for Tcl and X11, v8.4 - manual pages tk8.5-dev - Tk toolkit for Tcl and X11, v8.5 - development files tk8.5-doc - Tk toolkit for Tcl and X11, v8.5 - manual pages tk8.5 - Tk toolkit for Tcl and X11, v8.5 - run-time files tkcon - Enhanced interactive console for developing in Tcl tkgate-data - Event driven digital circuit simulator with Tcl/Tk tkgate-doc - Event driven digital circuit simulator with Tcl/Tk tkgate - Event driven digital circuit simulator with Tcl/Tk tkinfo - Tcl/Tk Info browser libtktable2.9 - Table extension for Tcl/Tk vtk-examples - C++, Tcl and Python example programs/scripts for VTK vtk-tcl - Tcl bindings for VTK tclxapian - Xapian search engine interface for Tcl xotcl-dev - Extended Object Tcl (XOTcl): Object orientation for Tcl - development files xotcl-doc - Extended Object Tcl (XOTcl): Object orientation for Tcl - manual xotcl-shells - Extended Object Tcl (XOTcl): Object orientation for Tcl - shells xotcl - Extended Object Tcl (XOTcl): Object orientation for Tcl - shared library aolserver4-xotcl - Extended Object Tcl (XOTcl): orientação a objetos para o AOLServer - módulo ewipe - Mais outra ferramenta de apresentação baseada em Tcl/Tk tk8.4 - kit de ferramentas Tk para Tcl e X11, v8.4 - arquivos em tempo de execução blt - a biblioteca de extensão BLT para Tcl/Tk - pacote de execução cableswig - gera invólucros para Python e Tcl a partir de código C++ amsn - um mensageiro MSN escrito em Tcl aolserver4-nscache - módulo AOLserver 4: API Tcl para os Caches do AOLserver tclx8.3-dev - Tcl Estendido versão 8.3.5 -- pacote de desenvolvimento TclX tkx8.3 - Tcl estendido (TclX) versão 8.3.5 -- pacote de tempo de execução TkX tcl8.4 - Tcl (Tool Command Language) v8.4 - arquivos de tempo de execução tkdvi - Um previsualizador TeX DVI baseado em Tcl/Tk. blt-dev - a biblioteca de extensão BLT para Tcl/Tk - arquivos de desenvolvimento bwidget - um conjunto de "widgets" de extensão para Tcl/Tk blt-demo - a biblioteca de extensão BLT para Tcl/Tk - demonstrações e exemplos bookview - cliente NDTP (Network Dictionary Transfer Protocol) baseado em Tcl/Tk postgresql-pltcl-8.3 - PL/Tcl procedural language for PostgreSQL 8.3 libdb4.8-tcl - Berkeley v4.8 Database Libraries for Tcl [module] postgresql-pltcl-8.4 - PL/Tcl procedural language for PostgreSQL 8.4 libtcltk-ruby1.9.1 - Tcl/Tk interface for Ruby 1.9.1 znc-tcl - an advanced IRC bouncer (Tcl extension)
Quer mais? :^)
Por exemplo, para instalar no Debian todos os pacotes (binários, documentação e desenvolvimento) da versão 8.5 do Tcl e Tk basta rodar o comando (como root):
bash#
apt-get install tcl8.5 tcl8.5-dev tcl8.5-doc tk8.5 tk8.5-dev tk8.5-doc
E em seguida executar o interpretador de Tcl puro com o comando tclsh ou associado com a biblioteca Tk com o comando wish.
Os pacotes, ou extensões, oferecem novas funcionalidades para o programador e podem ser instaladas de duas formas, compilando o código fonte ou instalando um pacote pré-compilado.
Esses pacotes precisam ser instalados em locais pré-definidos onde o interpretador Tcl procura por pacotes. A variável especial auto_path
armazena a lista de diretórios onde o interpretador procura por pacotes.
Podemos visualizar o conteúdo da variável auto_path
abrindo o interpretador no modo interativo e executando o comando puts $auto_path
bash$ tclsh % puts $auto_path /usr/share/tcltk/tcl8.4 /usr/lib /usr/local/lib/tcltk /usr/local/share/tcltk /usr/lib/tcltk /usr/share/tcltk %
O ActiveTcl vem com um utilitário prático chamado Teacup que facilita a instalação de pacotes pré-compilados localiza o(s) pacote(s) e verificando dependências. O Teacup utiliza um repositório externo chamado Teapot mantido pela empresa ActiveState.
A linguagem Tcl é de fácil aprendizado e com muitos recursos. O próprio interpretador oferece dicas sobre a sintaxe correta dos comandos.
Por exemplo, se você digitar apenas o comando puts terá o seguinte retorno:
% puts wrong # args: should be "puts ?-nonewline? ?channelId? string"
Nesta mensagem o interpretador está informando que o comando puts exige uma string e aceita alguns argumentos opcionais (entre sinais de interrogação) “nonewline” e “channelID”.
O interpretador Tcl lida apenas com comandos (instruções) e argumentos. Cada linha distinta começa com um comando seguido do(s) argumento(s) necessários. Se a linha ficar muito grande, encerre a linha com o indicador de continuação de linha ("\" barra invertida).
Por exemplo:
button .b1 -text "Meu primeiro botão" -command { exit } pack .b1
ou
button .b1 \ -text "Meu primeiro botão" \ -command { exit } pack .b1
Vai gerar um botão, figura abaixo, que irá fechar o interpretador ao ser clicado.
Para testar o código acima, no Linux, abra um terminal e digite wish para abrir o interpretador em modo interativo. No prompt (%
) que aparecer digite os comandos.
Além da barra invertida, itens entre chaves ({ e }) podem ultrapassar várias linhas, conforme o if abaixo:
if {$i<5} then { puts "$i é menor que 5" }
O comando if acima é uma linha para o Tcl.
Comandos e argumentos são separados por espaços, mas se você quiser colocar espaços em um argumento, pode colocar todo o argumento entre aspas:
puts "$i é menor que 5"
Como toda linguagem de programação o Tcl permite que você armazene um valor (ou uma lista de valores) em uma variável, a qual recebe um nome para ser identificada e para a qual se atribui um conteúdo para ser armazenado. Para a atribuição de valor para uma variável use o comando set.
set var 6
No comando acima o valor "6" foi atribuído à variável chamada "var".
Quando você digitar o comando, notará que o wish imprimirá o valor atribuído à variável.
% set var 6 6
Variáveis em Tcl são armazenadas como strings, embora o exemplo anterior pudesse enganá-lo fazendo achar que fosse um número.
A string "Maria" também pode ser armazenada na variável "var".
% set var Maria Maria
Para ler o conteúdo de uma variável utilize o caracter "$" (cifrão)
O cifrão significa a substituição de variável, por isso coloque $ antes do nome da variável, por exemplo $var, para que o interpretador substitua o valor atual mantido em var.
Experimente:
puts var
e compare com
puts $var
O comando puts é a abreviação de put string e imprime o argumento na saída padrão, terminal.
O comando expr é usado para operações matemáticas.
expr 2 * 6
ou
expr 2 * $var
Quando precisar salvar o resultado de um comando e usar o resultado como argumento para outro comando use os colchetes "[" e "]".
set var2 [expr 2 * 6]
ou
set var2 [expr 2 * $var]
No código anterior a parte [expr 2 * 6] é executada primeiro, e o resultado 12 é substituído para formar o comando set var2 12
Os colchetes também podem ser usados dentro de aspas.
% puts "O resultado de 2 x 6 é [expr 2 * 6]" O resultado de 2 x 6 é 12 %
Basicamente todas as variáveis em Tcl são consideradas como string e a Tcl converte o valor de uma variável para o tipo adequado no momento da execução.
Por exemplo:
set x "2"; expr $x + 3 5 % set x "texto"; expr $x + 3 syntax error in expression "texto + 3": variable references require preceding $
Na primeira linha a string “2” foi convertida para um tipo inteiro pelo comando expr e retorna o valor correto. Mas no segunda caso a string “texto” gera uma mensagem de erro porque não pode ser convertida.
Portanto o conteúdo de uma variável pode ser tratada como um número, uma string ou um valor lógico, dependendo do contexto.
Uma lista é uma sequência ordenada de elementos tais como strings, outras listas, e outras variáveis. Para criar uma lista, você pode usar o comando list:
% set minhaLista [list elemento1 elemento2 elemento3] elemento1 elemento2 elemento3 %
Neste exemplo criamos uma lista com três elementos, separados por espaços em branco e atribuímos a lista à variável minhaLista
.
Mas uma lista também pode ser criada com o comando:
% set minhaLista "elemento1 elemento2 elemento3" elemento1 elemento2 elemento3 %
Você poderá perguntar: Então qual a utilidade do comando list?
A vantagem do comando list é que ele cuida da formatação correta, acrescentando chaves e barras invertidas quando necessário.
O uso de listas permite organizar e estruturar além de permitir o uso de vários comandos que manipulam listas.
O comando llength retorna o número de elementos de uma lista.
% set minhaLista [list elemento1 elemento2 elemento3] elemento1 elemento2 elemento3 % llength $minhaLista 3
O comando lindex retorna o elemento de uma lista. O comando recebe como argumento a lista e um índice.
% set minhaLista [list elemento1 elemento2 elemento3] elemento1 elemento2 elemento3 % lindex $minhaLista 0 elemento1 % lindex $minhaLista 1 elemento2 % lindex $minhaLista 2 elemento3
Também é possível criar uma lista com sublista(s).
% set minhaLista [list 1 2 [list outra lista aqui]] 1 2 {outra lista aqui}
E resgatar elementos da lista e da(s) sublista(s) (com um índice adicional).
% set minhaLista [list 1 2 [list outra lista aqui]] 1 2 {outra lista aqui} % lindex $minhaLista 1 2 % lindex $minhaLista 2 outra lista aqui % lindex $minhaLista 2 1 lista
A linguagem Tcl oferece comandos que permitem desvios e instruções tais como if-then (se-então), for (até que) e while (enquanto).
O formato básico de um comando if é:
if {condição} then {instruções}
Exemplo:
set x 0 if {$x < 10} then { puts "$x é menor que 10" }
Se o resultado da condição {$x < 5} for verdadeiro (1), então as instruções serão executadas. Se o resultado da condição for falso (0), então as instruções não serão executadas.
O formato básico de um comando for é:
for {início} {condição} {incremento} {instrução}
for {set x 0} {$x < 5} {incr x} {puts "x vale $x"}
ou
for {set x 0} {$x < 5} {incr x} { puts "x vale $x" }
% for {set x 0} {$x < 5} {incr x} {puts "x vale $x"} x vale 0 x vale 1 x vale 2 x vale 3 x vale 4 %
Neste caso a variável x é inicializada com o valor 0 e se a condição {$x < 5} for verdadeira a instrução puts "x vale $x" é executada.
Em seguida é executado o comando incr x, incrementando em uma unidade o conteúdo da variável x. Novamente a condição {$x < 10} é avaliada, se for verdadeira repete-se o ítem anterior e se for falsa o loop é encerrado.
O formato básico de um comando while é:
while {condição} {instrução}
Exemplo:
set x 0 while {$x < 10} { puts "x vale $x" incr x }
A variável x é inicializada com o valor 0, em seguida é feito um teste, se {$x < 10} for verdadeiro são executadas as instruções puts "x vale $x" e incr x.
Em cada passagem pelo loop, o valor de x é incrementado em uma unidade, enquanto x for menor que 10, até o conteúdo da variável x for igual a 10, quando então o loop while é encerrado.
O foreach é usado para interagir com “listas”, executando um comando ou um script para cada item de uma lista de itens.
Possui a seguinte sintaxe:
foreach variável lista { comandos }
% foreach numero {1 2 3 4 5} { puts "porta serial $numero" } porta serial 1 porta serial 2 porta serial 3 porta serial 4 porta serial 5
Em cada iteração o loop foreach atribui a uma variável um elemento da lista, percorrendo-a até que todos os itens da lista tenham sido lidos.
O script seguinte faz a mesma coisa, porém, não recebe uma lista diretamente e sim uma variável que contém uma lista (numeros
).
% set numeros {1 2 3 4 5} 1 2 3 4 5 % foreach numero $numeros { puts "porta serial $numero" } porta serial 1 porta serial 2 porta serial 3 porta serial 4 porta serial 5 %
O foreach também pode iteragir com duas listas simultâneamente.
% set numeros {1 2 3 4 5} 1 2 3 4 5 % set inst {pHmetro bomba válvula espectrofotômetro balança} pHmetro bomba válvula espectrofotômetro balança % foreach numero $numeros instrumento $inst { puts "$instrumento usa porta serial $numero" } pHmetro usa porta serial 1 bomba usa porta serial 2 válvula usa porta serial 3 espectrofotômetro usa porta serial 4 balança usa porta serial 5 %
O comando proc registra um procedimento por nome e permite que você o execute como qualquer outro comando em Tcl. A sintaxe é:
proc nome_do_procedimento {argumentos} {instruções}
Exemplo:
proc somar_dois { valor } { return [expr $valor + 2] }
A partir daí o procedimento somar_dois estará pronto para ser usado a qualquer momento no futuro.
Por exemplo:
somar_dois 5 7
Desenvolver, em Tcl, um programa que calcule a soma dos N números inteiros (1, 2, 3, ... N) e mostre o resultado final.
Vamos lembrar do diagrama de fluxo do exercício 1 e implementar aquela lógica usando a linguagem Tcl.
Resolução! Mas antes tente fazer ! :)
Sugestão crie um procedimento do tipo:proc soma { N } { ... }
Antes de continuar, vamos digitar os comandos em um arquivo texto usando um editor de texto puro (Notepad - Windows), (Emacs - Linux) e salvar com o nome exemplo.tcl.
#!/bin/sh #A próxima linha reinicia usando o wish \ exec wish "$0" "$@" proc soma { N } { set A 0 set B 0 while {$A < $N} { incr A set B [expr $B + $A] } puts "A soma dos $N primeiros números inteiros é $B" } soma 1 soma 2 soma 4 soma 5
A primeira linha do script exemplo.tcl usa um truque interessante do Linux. Colocando um comentário especial na primeira linha de um script, começando com #!, o shell Linux passará o arquivo script para o programa adequado, neste caso o wish.
A etapa seguinte para fazer o script rodar é tornar o arquivo exemplo.tcl executável. Em um terminal digite:
chmod +x exemplo.tcl
E o script poderá ser executado a partir da linha de comando como qualquer outro programa.
A presença dos dois caracteres “#!” (shebang em inglês) no início de um arquivo executável informa o carregador do programa que o arquivo é um script e também especifica o interpretador que deve ser usado para executá-lo.
O capeçalho do tipo “#!/usr/bin/tclsh” especifica que o script deve ser interpretado pelo programa tclsh (ou “#!/usr/bin/wish”) cujo path é /usr/bin
. No entanto se você tentar rodar esse script em um sistema onde o tclsh não estiver no diretório /usr/bin
ele não vai rodar e portanto essa não é uma boa estratégia pois torna o código pouco portável.
[3]
Uma alternativa mais conveniente é usar:
#!/bin/sh #Script exemplo \ exec tclsh "$0" "$@"
Neste caso o script é interpretado pelo shell sh que é incapaz de executar os comandos Tcl mas vai executar o comando exec.
O comando exec chama o interpretador tclsh e passa os argumentos “$0” (nome do script) e “$@” (demais argumentos passados para o shell).
O truque neste caso é evitar que a Tcl execute o comando exec (um comando também da Tcl) mas apenas o sh execute o comando exec. Para evitar que isso aconteça usa-se a barra invertida “\” no final da segunda linha para que a Tcl considere a segunda e terceira linha como um único comentário. Enquanto que o sh considera apenas a segunda linha como comentário e a terceira linha como um comando a ser executado. ;^)
Uma outra alternativa que vem ganhando popularidade é:
#!/usr/bin/env tclsh #Script exemplo puts "Oi Mundo!"
O comando env executa o comando tclsh usando a avariável PATH
do sistema.
Mas para usar os widgets Tk, é necessário usar o interpretador wish:
#!/bin/sh #Script exemplo \ exec wish "$0" "$@"
ou
#!/usr/bin/env wish #Script exemplo puts "Oi Mundo!"
Para acessar um arquivo, ou seja, ler ou escrever dados, é preciso criar um “canal” para o arquivo, o que é feito em Tcl com o comando open.
O comando open gera (ou retorna) um “descritor de arquivo” ou identificador), ou seja, um nome para o canal que será usado para ler ou escrever dados no arquivo.
Por exemplo, se eu tiver um arquivo chamado arquivo.txt
posso criar um canal para esse arquivo digitando em um terminal o comando:
% open arquivo.txt file5
E a Tcl cria automaticamente o identificador file5
para o canal criado para acessar o arquivo.txt
.
Na prática esse nome é armazenado em uma variável para ser usado posteriormente em operações de leitura e escrita:
% set nome_canal [open arquivo.txt] file5 % puts $nome_canal file5 %
No exemplo acima criei um canal para arquivo.txt
e armazenei o identificador na variável nome_canal
, cujo conteúdo pode ser visualizado com o comando puts $nome_canal
.
Outro aspecto importante na manipulação de arquivos é o “modo de acesso” que pode ser: somente leitura, somente escrita ou leitura e escrita.
O modo de acesso pode ser definido com o uso dos parâmetros: r
, r+
, w
, w+
, a
e a+
.
A tabela seguinte resume os diferentes modos de acesso do comando open.
Tabela 5. Parâmetros do comando open e os diferentes modos de acesso de um canal.
Parâmetro | Leitura | Escrita | Posição inicial do “ponteiro” (ou cursor) | Arquivo deve existir? | Conteúdo do arquivo é apagado? |
---|---|---|---|---|---|
r | Sim | Não | Início do arquivo | Sim | Não |
r+ | Sim | Sim | Início do arquivo | Sim | Não |
w | Não | Sim | Início do arquivo | Não | Sim |
w+ | Sim | Sim | Início do arquivo | Não | Sim |
a | Não | Sim | Fim do arquivo | Não | Não |
a+ | Sim | Sim | Fim do arquivo | Não | Não |
Em resumo: (Fonte: Tcl/Tk - Programação Linux, 2005)
r - Abre o arquivo apenas para leitura, e o arquivo deve existir.
r+ - Abre o arquivo para leitura e escrita (gravação) e o arquivo deve existir.
w - Abre o arquivo para gravação não-incremental, ou seja, se o arquivo já existir seu conteúdo original será apagado e serão escritos novos dados.
w+ - Abre o arquivo para leitura e gravação não-incremental.
a - Abre o arquivo para gravação incremental, ou seja, se o arquivo já existir, seu conteúno não será apagado e qualquer novo dado escrito será adicionado a partir do final do arquivo.
a+ - Abre o arquivo para leitura e gravação incremental.
Por exemplo, vou criar um arquivo redirecionando a saída do comando ls para o arquivo arquivos.txt
.
$
ls > arquivos.txt
Em seguida vamos criar sript que vamos chamar ler_arquivo.tcl
que vai abrir um canal para o arquivo arquivos.txt
e exibir o seu conteúdo na tela.
#!/usr/bin/env tclsh #Script ler_arquivo.tcl set nome_canal [ open arquivos.txt r ] while { ! [ eof $nome_canal ] } { set linha [ gets $nome_canal ] puts "Esta linha contém: $linha" }
Vou alterar as permissões [4] deste script para torná-lo executável com o comando:
$
chmod 744
ler_arquivo.tcl
E ao executar este script em um terminal vemos o conteúdo do arquivo arquivos.txt
:
$ ./ler_arquivo.tcl Esta linha contém: arquivos.txt Esta linha contém: medidor_multiparametro_00.tcl Esta linha contém: medidor_multiparametro_00.tcl~ Esta linha contém: medidor_multiparametro.db Esta linha contém: multipar00.tcl Esta linha contém: multipar00.tcl~ Esta linha contém: objLab Esta linha contém: simu_orion.tcl Esta linha contém: teste.csv Esta linha contém:
O script ler_arquivo.tcl
abre o arquivo arquivos.txt
somente para leitura (r) e em seguida entra em um loop while enquanto o final do arquivo não for atingido. Para isso foi usado o comando eof em conjunto com o operador de negação (!). O comando gets serve para ler a próxima linha do canal e armazena o que foi lido na variável linha
. E finalmente o comando puts exibe na tela a mensagem Esta linha contém:
seguido do conteúdo da variável linha
. Esses comandos são executados até que o final do arquivo seja encontrado. (Fonte: Tcl/Tk - Programação Linux, 2005)
Vamos criar um botão que vai chamar a execução do programa anterior, para tanto, vamos anexar as linhas abaixo:
button .b1 -text "Executar o programa soma" -command {soma 5} pack .b1
Na primeira linha o comando button cria um botão chamada .b1 (o ponto é importante).
Assim como o Linux usa o caractere (/) para marcar o diretório raiz do sistema de arquivos a Tcl usa o ponto (.) para marcar o widget raiz (a janela principal do seu aplicativo).
Estamos então criando um widget button (.) que se comporta como um widget filho do widget pai (.).
A opção -command determina qual o comando Tcl que irá funcionar quando o botão for "clicado", neste caso ele chama o procedimento soma com o argumento 5.
Os widgets são criados mas permanecem invisíveis até que um comando de gerenciamento de geometria seja usado, neste caso pack.
#!/bin/sh #A próxima linha reinicia usando o wish \ exec wish "$0" "$@" proc soma { N } { set A 0 set B 0 while {$A < $N} { incr A set B [expr $B + $A] } puts "A soma dos $N primeiros números inteiros é $B" } button .b1 -text "Executar o programa soma" -command {soma 5} pack .b1
Ao executar o programa acima em um terminal, você verá o botão que irá chamar o programa ao ser clicado, exibindo no terminal a mensagem A soma dos 5 primeiros números inteiros é 15
Do jeito que o programa está o valor de N é fixo e vale 5.
Para poder rodar o programa com diferentes valores de N vamos usar um widget chamado entry(entrada).
Para isso basta incluir a linha:
entry .entrada -relief sunken -background white -textvariable N
Onde entry é o comando de criação do widget com o nome .entrada.
A opção -relief define o relevo 3D do widget e pode assumir as opções: flat, groove, raised, ridge, sunken.
A opção -background define a cor de fundo e finalmente a opção -textvariable permite definir uma variável (N) que vai armazenar o que o usuário digitar dentro do entry.
Só falta substituir o número 5 pelo conteúdo da variável N ($N) na linha de criação do botão.
#!/bin/sh #A próxima linha reinicia usando o wish \ exec wish "$0" "$@" proc soma { N } { set A 0 set B 0 while {$A < $N} { incr A set B [expr $B + $A] } puts "A soma dos $N primeiros números inteiros é $B" } button .b1 -text "Executar o programa soma" -command {soma $N} pack .b1 entry .entrada -relief sunken -background white -textvariable N pack .entrada
Agora vamo incluir o widget text na própria janela do programa para que a saída seja exibida na interface gráfica.
#!/bin/sh #A próxima linha reinicia usando o wish \ exec wish "$0" "$@" #exemplo.tcl entry .entrada -relief sunken -background white -textvariable N pack .entrada button .b1 -text "Executar o programa soma" -command {soma $N} pack .b1
text .texto -background white -foreground black -width 50 -height 10
pack .texto
proc soma { N } { set A 0 set B 0 while {$A < $N} { incr A set B [expr $B + $A] }
.texto insert end "A soma dos $N primeiros números inteiros é $B\n"
}
Deixei em destaque as linhas adicionadas para criar o widget text.
A primeira linha:
text .texto -background white -foreground black -width 50 -height 10
cria o widget text com o nome .texto, com fundo branco (-background white), letras pretas (-foreground black), largura 50 (-width 50) e altura 10 (-height 10).
A segunda linha, pack .texto, usa o gerenciador de posição pack para exibir o widget .texto.
E finalmente troquei o comando
puts "A soma dos $N primeiros números inteiros é $B"
pelo comando
.texto insert end "A soma dos $N primeiros números inteiros é $B"
para inserir o resultado diretamente no final (end) do widget .texto.
Espero ter ajudado a dar os seus primeiros passos com a linguagem Tcl/Tk. A partir de agora vamos mostrar algumas aplicações dessa linguagem para a Automação em Laboratório, que é o nosso tema principal!
Curso sobre Tcl/Tk - Curso em português sobre Tcl/Tk.
Curso sobre Tcl/Tk do Rildo Pragana - Informações em português sobre Tcl/Tk
Site do Rildo Pragana - Muitos programas escritos em Tcl/Tk
SITE OFICIAL - Site Oficial da linguagem Tcl, criada por John K. Ousterhout.
Site sobre Tcl/Tk do Ricardo Jorge - Neste site você encontra diversos links e informações sobre a Tcl/Tk
Site sobre Tcl/Tk do Wesley R. Braga - Páginas de manual da Tcl/Tk.
SITE WIKI SOBRE TCL/TK - Site Wiki (com conteúdo editável pelos visitantes) sobre Tcl/Tk
WIKI - TCL- Site Wiki sobre Tcl em português.
[2] Compilação é conversão (ou tradução) do código fonte de uma linguagem de programação de alto nível para uma linguagem de programação de baixo nível.
Normalmente, o código fonte é escrito em uma linguagem de programação de alto nível (compreensível para humanos) e o código compilado é escrito em uma linguagem de baixo nível como uma sequência de instruções a ser executada pelo microprocessador. (Fonte: Wikipedia)
[3] Portabilidade de um programa de computador é a sua capacidade de ser compilado ou executado em diferentes sistemas (Linux, Windows etc).
[4] O Linux é um sistema multiusuário o que significa que um mesmo PC ou servidor pode ser acessado por vários usuários simultâneamente. Com isto, surge a necessidade de algum sistema de segurança que limite o que cada usuário pode fazer no sistema, para que não haja o risco de que um usuário possa destruir arquivos ou configurações do sistema ou de outros usuários. Isto é feito através das permissões de arquivos. (Fonte: Entendendo e Dominando o Linux)
Veja com mais detalhes uma explicação bem completa sobre permissões de acesso no Guia Foca Linux