Tcl/Tk
Faz mais de um mês que não escrevo nada sobre Informática! Como já faz tempo que quero escrever sobre Tcl/Tk, vamos lá!
Tcl (Tool Command Language) é uma linguagem de script de código aberto muito poderosa. Desenvolvido por John Ousterhout, é costume dizer que é uma linguagem fácil, mas discordo.
É baseada em comandos (há uma variante orientada a objetos, chamada [incr Tcl]) com uma proposta interessante: tudo são strings!
Uma string em Tcl não precisa de delimitador, a menos que possua caracteres não-permitidos, como espaço e mudança de linha. Neste caso, o delimitador padrão é " (ou chaves).
Vamos a alguns exemplos...
Para se alterar ou ler o valor de uma variável usa-se o comando set. No exemplo a seguir, o script lê o valor da variável e retorna o dobro:
puts -nonewline stdout {Informe um número: }
gets stdin num
set num [expr [set num] * 2]
puts stdout "O dobro é [set num]"O primeiro comando (
puts) grava na saída padrão (stdout, a tela) a string «Informe um número: » sem mudar de linha (-nonewline). As chaves ({...}) também delimitam uma string, mas não interpretam colchetes (veja adiante).Então o comando
gets lê da entrada padrão (stdin, o teclado) um valor e atribui à variável num.No próximo comando,
set, usamos colchetes ([...]). Os colchetes interpretam um comando e são substituídos por seu retorno.Ou seja, se foi atribuído o número 123 à variável
num, no comando:expr [set num] * 2A parte entre colchetes,
set num, retorna o valor de num, portanto 123, então os colchetes serão substituídos, recriando a string do comando assim:expr 123 * 2O comando
expr avalia uma expressão matemática e retorna seu valor. Então:set num [expr [set num] * 2]Calcula o dobro do conteúdo de
num e atribui a num.O último comando grava na saída padrão (exibe na tela, ora pois!) a string «
O dobro é [set num]», substituindo os colchetes pelo valor de num.Repare que no primeiro
puts, a string está protegida por chaves, e no segundo por aspas. Sempre dou preferência ao uso de chaves, mas as chaves protegem a string de interpretação, enquanto que aspas permitem a interpretação de colchetes (e cifrão, veja a seguir).Agora, há um jeito de simplificar este código: seguindo as sintaxes de Shell e de Perl, existe uma forma simplificada de escrever
set num com cifrão ($):puts -nonewline stdout {Informe um número: }
gets stdin num
set num [expr $num * 2]
puts stdout "O dobro é $num"Estruturas de controle
Dada a introdução, quero agora comentar algumas estruturas de controle de fluxo...
O primeiro comando é
if. Sua estrutura é assim: if condição bloco1 [else bloco2]. Aqui, condição, bloco1 e bloco2 são strings (como não poderia deixar de ser). Então:if {$sair == 1} {
puts stdout Tchau
exit
}Se o conteúdo da variável
sair for igual a um, exibe Tchau e sai. Como em outras linguagens, o bloco do else é executado se a condição for falsa.A igualdade dupla (
==) é usada para comparar valores numéricos. Para a comparação de strings, é usado o comando string com a opção equal:if [string equal $var1 $var2] {
puts stdout {São iguais!}
} else {
puts stdout {São diferentes!}
}Se quiser uma comparação ignorando maiúsculas e minúsculas, é só usar
string equal -nocase. Repare que aqui a string interpretada pelo if como condição não é o comando em si, mas seu resultado.Outro comando é o famigerado
for.A estrutura:
for inicialização condição passo bloco. Novamente cada termo é uma string.Vamos a um exemplo simples:
for {set i 0} {$i < 10} {incr i} {puts stdout $i}Vai exibir todos os número de 0 a 9. Mas o comando é feio e difícil de guardar, né?
Então, existe um variante do Tcl chamado TclX (Tcl estendido), com um comando muito útil:
loop.loop i 0 10 {
echo $i
}O comando
echo de TclX é equivalente a puts stdout de Tcl. Em loop é possível passar mais um argumento entre o máximo e o bloco como passo (tipo: loop i 0 20 2 {...).Obs.: TclX aceita todos os comandos de Tcl e implementa (estende) mais alguns.
Outros comandos de controle de fluxo interessantes em Tcl são:
while, switch e foreach.Funções
O comando para criar uma função é
proc, que recebe como primeira string a lista de argumentos (separados por espaços) e como segunda string o bloco de comandos. Ex.:proc fib n {
set a 0
set b 1
set c 1
while {$c <= $n} {
set aux $a
set a $b
incr b $aux
incr c
}
return $b
}Então
fib vai calcular a sequência de Fibonacci:for {set i 0} {$i < 10} {incr i} {
puts stdout [fib $i]
}Tk
Agora a parte mais interessante: Tk!
Tk é o toolkit gráfico de Tcl. O comando para usar Tcl com Tk é
wish (e para usar TclX com Tk é wishx).Em Tk a janela raiz é representada por um ponto (
.).Vamos criar um olá mundo!!!
#!/bin/sh
#\
exec wish "$0" "$@"
tk appname Ola
tk_setPalette gray
label .lbOla -text {Olá Mundo!!!}
button .btOk -text Ok -command exit
pack .lbOla .btOkAs três primeiras linhas são um cabeçalho pra podermos tornar o script executável.
O primeiro comando (
tk appname) define o nome da aplicação (Ola), e o comando seguinte (tk_setPalette) diz pra usar como cores variantes de cinza (gray).O comando
label cria um rótulo (label) chamado lbOla na janela raiz (.) com o texto «Olá Mundo!!!». O comando button cria um botão chamado btOk na janela raiz (.) com o texto «Ok» e que, ao ser clicado (-command), executa exit (sair).O comando
pack indica que será usado o geometry manager pack. Geometry managers são gerenciadores de widgets (objetos gráficos) e geometria. Tk usa três: pack («empacota» em relação a posições esquerda, direita, em cima, em baixo, e tenta manter estas relações), grid (usa uma tabela – grade – colocando os widgets nas células da tabela) e place (desaconselhável: coloca os widgets em posições absolutas).O gerenciador
pack por padrão coloca os widgets a partir de cima (top), um de baixo do outro, centralizando (é possível mudar isso usando -side).Para colocar os widgets um do lado do outro a partir da esquerda, usa-se
-side left, a partir da direita: -side right. Para «amarrar» um widget em baixo, usa-se -side bottom.O
grid prende os widgets centralizados (é configurável) em células. A célula exata é informada através dos números de linha (-row) e coluna (-column). É possível que um widget ocupe mais de uma coluna (-columnspan) ou mais de uma linha (-rowspan).O script acima poderia ser reescrito usando
grid assim:#!/bin/sh
#\
exec wish "$0" "$@"
tk appname Ola
tk_setPalette gray
label .lbOla -text {Olá Mundo!!!}
button .btOk -text Ok -command exit
grid .lbOla -row 0 -column 0
grid .btOk -row 1 -column 0Para saber mais
O melhor lugar para se encontra mais informações sobre Tcl/Tk é na secção
(n) (new) das manpages, mas um macete indispensável é digitar o seguinte comando no shell de um xterm:tcl <<< tclhelp[]'s
PS: Procure screenshots no Google!

