Make your own free website on Tripod.com
logo titulo
anterior indice proximo

Linguagens de scripting


O que nos motiva a procurarmos outros tipos de linguagens? As existentes já não são suficientemente poderosas? Ademais, porque linguagens interpretadas? Não seria mais rápido usar uma linguagem como C ou C++ e escrever um programa portável, eficiente e robusto?

Estas perguntas nos vêm à cabeça quando tentamos explicar o motivo da corrida na última década para as linguagens de "scripting", ou seja linguagens interpretadas. De Java a Perl, Python, Scheme ou Tcl, todas são linguagens que têm essa característica comum. A razão dessa popularidade se deve a diversos fatores:

Neste capítulo veremos alguns exemplos em Tcl/tk, por considerarmos a linguagem (desta classe de linguagens) mais fácil de se usar e produtiva. Com o toolkit tk, o programador poderá criar "embrulhos" para tornar mais simples a utilização de comandos tradicionais do Linux, tornando mais simples a utilização do sistema por um usuário totalmente sem experiência. O tcl/tk é facilmente extensível (em C por exemplo) e já está interfaceado com a maioria das linguagens existentes no planeta (prolog, scheme, e mesmo outras linguagens de scripting como falamos anteriormente). Existem extensões do tk toolkit para gráficos científicos, interfaces com praticamente todos os servidores SQL (para bancos de dados), extensões para música, interfaces com o TeX/LaTeX, e inúmeros widgets adicionais como, por exemplo, o Tix, que cria aplicações com todos os tipos de objetos suportados pelo ambiente Windows(MR da Microsoft Corp.). Com o tcl plug-in, browsers como o Netscape podem executar (no lado do cliente) aplicações na forma de scripts sem o acesso ao fonte do programa.

Vejamos o que pode ser construido com poucas linhas de tcl/tk:

label .ex -text "Exemplo em tcl"
button .sai -text saida -command exit
pack .ex .sai
tcl-exemp

Cada uma destas linha é um comando. O label cria o texto na parte de cima (Exemplo em tcl) e batiza o objeto com o nome .lab. O button cria o botão na parte de baixo e o chama de .but, associando a este um texto (saida) e o comando exit, para quando este botão for pressionado. Finalmente, o pack "empacota" os dois, usando a ordem default de cima para baixo, de foma a ocupar exatamente a cavidade da janela.

O gerenciador de arquivos tkdesk, que mostramos (somente a figura) no primeiro capítulo, é um programa escrito em tcl/tk, se bem que mais complexo (muito mais) que esse nosso programa de 3 linhas.

Os comandos em tcl têm sempre a mesma sintaxe: cmd arg arg arg ...
O que dita o número de argumentos é a definição da sua função (procedure). De certo modo é semelhante a um shell, mas com algum "sabor" de C e até de Lisp, e foi concebida na forma de uma biblioteca para ser incorporada a aplicações na forma de uma linguagem embutida (embedded language). Pelo menos era essa a intenção histórica do seu autor (J. Ousterhout). Contudo, sua simplicidade e expressividade fez com que várias aplicações fossem construidas somente na forma de scripts, sem nenhum código adicional em C, por exemplo.

Substituições são realizadas em variáveis como no shell, prefixando a variável com um "$". Substituição de comandos com colchetes [...] (aproximadamente o equivalente a `...` no shell. Finalmente quoting é feita pela barra invertida "\".
Dois ou mais possíveis strings podem ser agrupados por aspas "str1 str2 ..." para formar um único argumento, mas substituiçóes como as feitas por "$" (valor de variáveis) ou "\" (o próximo caracter literalmente) são realizadas livremente, bem como substituição de comandos. Outro tipo de agrupamento é realizado por um par de chaves {...}, que previne toda e qualquer substituição.

Em tcl, somente um data type exite, strings. Arranjos (arrays) são associatiovs, isto é, o índice pode ser qualquer string, o que pode ser útil para simular arrays multidimensionais usando dois índices (por exemplo numéricos) separados por uma vírgula. Um processo de hashing faz a pesquisa de variáveis (e funções também) ser bastante rápida. Por sinal, o código é parcialmente compilado, o que reduz consideravelmente a penalidade imposta pela interpretação. A representação de comandos e dados de maneira homogênea permite a manipulação de programas como dados (herançá do Lisp), o que implica a facilidade para o programador criar novas estruturas de controle ou controle de erro simplesmente escrevendo uma função ordinária.

Tcl também facilita a escrita de código event driven (disparado por eventos) permitindo associar um trecho de código a ser executado quando uma variável é modificada, por exemplo.

tkcon

Nos exemplos a seguir o prompt do tcl é "%" (para a linha introduzida no terminal). Na prática é interessante usar um ambiente de desenvolvimento como o TkCon para realizar os testes, devido às suas facilidades de edição, por permitir "capturar" e se conectar a um programa já sendo executado para depuração, salvar ou ler código introduzido manualmente para posterior edição com um editor de textos qualquer. Apesar da imagem aparentemente simples do TkCon, este programa é bastante poderoso. Outro utilitário interessante de se usar durante o desenvolvimento é o tkinspect.

Uma variável é criada ou modificada pelo comando set. O que diferencia uma variável numérica de uma com uma string alfa-numérica é somente o valor (e a intenção do programador). O operador expr pode ser usado para calcular expressões aritméticas.

No primeiro e segundo comandos (listagem ao lado) atribuimos valores a duas variáveis (criadas nesse instante), uma numérica e outra literal. Note que, na realidade, as duas são meramente strings. O terceiro comando imprime uma frase contendo as variáveis (operador $ para fazer a substituição), mas precisa haver o agrupamento pelas chaves devido aos argumentos que puts espera.
No próximo comando o primeiro "$" é prefixado pela barra invertida, evitando a substituição (quoting). O quinto comando calcula o log(y)+1 e armazena-o em z1. Observe os colchetes, realizando a substituição de comando. Sem os colchetes, toda a string seria armazenada, e não o valor obtido com a operação. No próximo comando usamos o comando set para ler o conteúdo da variavel, observando a forma com um único argumento desse comando, e o detalhe que o nome da variável é passado como argumento para este comando e não o seu valor ($y).
Finalmente, o último comando tenta calcular uma expressão aritmética com um valor literal, o que, obviamente, resulta em um erro apontado pelo interpretador.

% set x Recife
Recife
% set y 1234
1234
% puts "$x e $y são diferentes"
Recife e 1234 são diferentes
% puts "\$x = $x"
$x = Recife
% set z1 [expr log($y)+1]
7.11801620447
% set z1
7.11801620447
% set z2 [expr $x+1]
syntax error in expression "Recife+1"

A representação de listas em tcl é na forma de expressões entre chaves, organizadas hierarquicamente. Vejamos um exemplo com listas :

 set frutas {{laranja azeda} maracujá graviola
   {acerola vitaminada} {manga deliciosa}} 

irá armazenar um frutas uma lista de tamanho 5, com 3 sub-listas. Algumas funções permitem manipulação com estas listas:

% lindex $frutas 0
laraja azeda
% lindex $frutas 2
graviola
% lindex $frutas 5
 (nada foi retornado) 
% llength $frutas
5
% llength [lindex $frutas 3]
2
% lappend frutas limão
{laranja azeda} maracujá graviola {acerola vitaminada} {manga deliciosa} limão
%

estruturas de controle


As estruturas de controle já definidas são semelhantes às da maioria das linguagens procedurais, mais o foreach para iterar sobre ítens de uma lista, e outras duas meta-estruturas (upvar e uplevel) que permitem ao programador criar outras estruturas mais apropriadas para o seu caso.

Vejamos um exemplo prático, usando a lista definida na seção anterior como exemplo. O objetivo é criar radiobuttons (botões que somente um fica ativado) para selecionar a fruta preferida do usuário. O resultado deverá ficar numa variável (fruta_escolhida), que será modificada quando outro radiobutton for pressionado.

foreach f $frutas { 
  if {[llength $f] > 1} {
    set rb [lindex $f 0]
  } else {  
    set rb $f 
  } 
  pack [radiobutton .rb$f -text $rb -variable fruta_escolhida 
    -value $f -anchor w }] -fill x -expand 1
}
radiobuttons

A implementação usa o comando foreach para repetir o procedimento para cada elemento da lista. Entretanto, tem um problema: a lista contém não somente elementos simples, mas também sub-listas. O condicional (if) verifica se é o caso e extrai na variável rb o valor que nos interessa. No final é só criar para cada fruta o radiobutton correspondente, já empacotando-o. Para criar nomes diferentes para cada radiobutton, adicionamos o nome da fruta no final da string .rb. As opções do comando radiobutton são visíveis: -text para indicar o texto que será mostrado no widget[37], -variable para a variável que será modificada quando este widget for selecionado, -value o valor a colocar nesta variável, -anchor para "ancorar" o widget pelo lado esquerdo (w=west=oeste). As outras são opções do pack, para preencher o espaço na direção x, expandindo os widgets se necessário.

tkinspect tkinspect

É interessante monitorar e interferir em um programa rodando. Esta ferramenta roda independentemente e "captura" um outro programa tcl/tk, habilitando o programador escolher variáveis, widgets, procedures (painel superior) e visualizar o código regenerado a partir do programa em execucão. Comandos podem ser enviados ao programa que está sendo monitorado, graças à função send presente no tcl. Dessa forma, o programa pode ser mesmo desenvolvido e testado numa velocidade muitas vezes maior que linguagens compiladas (por exemplo Delphi, que é tão popular no ambiente Windows).

spectcl SpecTcl

São muitos os editores visuais existentes para o tcl/tk. Este é um dos mais fáceis de usar, apesar de não ter a mesma flexibilidade do visual tcl ou do xf (um dos mais completos, mas relativamente complicado). O programador cria widgets via "drag & drop" dos modelos contidos à esquerda, pode selecionar valores para os atributos destes widgets e adicionar código executado quando algum evento ocorrer. (são muitos os tipos de eventos suportados pelo tcl/tk)

O SpecTcl trabalha somente com o geometry manager grid, apesar do tcl/tk ter 3 diferentes geometry managers. O visual tcl, por exemplo, não tem essa restrição. Nos exemplos acima usamos somente o pack.


rpragana
Fri Jan 15 16:45:56 EDT 1999