Aplicações do
    Tcl e Starkits


CBQ Recife - Outubro de 2012
Porque usar scripts?
●
    Interatividade: não há o ciclo “edita-compila-
    testa”.
●
    Menos linhas de código (alto-nível).
●
    Melhor representação dos dados (no Tcl, por
    exemplo, tudo é string).
●
    Portabilidade. (Linux (e outros unices),
    Windows, Mac, mobile, embedded, ...)
O que podemos fazer com Tcl?
●
    MITO: linguagens de script são muito lentas,
    não devem ser usadas em aplicações velozes
    (processamento de vídeo, por exemplo)
●
    REALIDADE: só uma pequena fração do
    código precisa ter velocidade extrema; scripts
    nos fornecem mais controle, flexibilidade e
    menos linhas de código.
Sintaxe do Tcl
●
    Todos os comandos na forma:
    comando arg1 arg2 …
    Exemplos de comandos:
    set nome “Rildo Pragana”
    set numero 1234
    puts $nome
    puts -nonewline “numero=$numero”
●
    Todos os tipos são equivalentes a
    strings (cadeia) de caracteres.
●
    Substituições:
    ●
        Variável  $variavel
    ●
        Comando [comando]
    ●
        Backslash  n t u00c7
Sintaxe 2
●
    Agrupando ítens:
    ●
        Com substituição:
        “cmd = $comandon data = [clock format $ck]”
    ●
        Sem substituição:
        {Nada disso é modificado: [teste], $}


●
    Expansão de argumentos: (evita uso de “eval”)
        set lsArgs {-l nota.txt}
        exec ls $lsArgs → não funciona
        eval exec ls $lsArgs → funciona mas expande tudo
        exec ls {*}$lsArgs → perfeito!
Listas
●
    Exemplos de listas:
    ●   set cores {azul amarelo vermelho branco}
    ●   set lst { {12.37 N} {-1.567 W} 135 }
●
    Alguns comandos:
    ●   list ?arg arg …?
    ●   lindex list ?index …?
    ●   lappend listVar ?value …?
    ●   linsert list index element ?element …?
    ●
        Outros: lreplace, llength, lsearch, lsort,
        lset, lrepeat, lrange
Arrays

●   Variável com um índice (hash)
    Exemplos:
      data(agora)
      v(1) v(2) …
      posicao(12.5,23.7)
●   Comando para manipular variáveis tipo array
    ●   array names arrayName ?mode? ?pattern?
    ●   array get arrayName ?pattern?
    ●   array set arrayName list
Dict (dicionário)
●   Lista de pares key (chave), valor
●
    Comandos mais comuns:
    ●   dict create ?key value …?
    ●   dict get dictVal ?key …?
    ●   dict set dictVariable key ?key …? value
    ●   dict size dictValue
    ●   dict keys dictValue ?globPattern?
    ●   dict for {keyVar valueVar} 
           dictValue body
Criando subcomandos (ensemble)
 namespace eval ::counter {
   variable counter 0
   namespace export get set incr
   namespace ensemble create
 }                                        Utilização:
                                          counter set 35
 proc ::counter::get {} {
   variable counter                       counter get
   return $counter                        counter incr
 }                                        counter incr -2
                                          set counter::counter
 proc ::counter::set {value} {
   variable counter
   return [::set counter $value]
 }

 proc ::counter::incr {{increment 1}} {
   variable counter
   return [::incr counter $increment]
 }
Starkits

●
    Scripts e extensões encapsulados em um único
    arquivo (.kit), portável (Linux/Windows/Mac)
●
    Executável separado para cada plataforma: tclkit,
    tclkit.exe
●
    Diretório virtual. Pode conter scripts, bibliotecas
    (multiplas versões, uma para cada OS),
    documentação. Implementado no topo do
    banco de dados Metakit.
Manipulando kits

●
    Utilitário sdx
    ●   sdx qwrap programa.tcl
        –   Gera um kit a partir do script fornecido
    ●   sdx unwrap programa.kit
        –   Expande o kit como o diretório programa.vfs
    ●   sdx wrap programa.kit
        –   Reempacota o kit usando o diretório programa.vfs
        –   Opcionalmente, podemos usar
            -runtime tclkit para produzir um starpack
            (tudo em um só executável).
Bibliotheca
Bibliotheca (2)
●
    Cada livro é representado por uma imagem
    (capa) de tamanho reduzido.
●
    Formatos dos arquivos (livros): pdf, djvu,
    chm, ps,...(outros podem ser suportados
    facilmente)
●
    Comandos para incluir novos livros,
    reorganizar as “estantes”, criar
    ícones para um livro, ou até para transferir o
    conteúdo (ssh) a
    partir de um servidor.
Bibliotheca (3)

●
    Informações sobre livros armazenados numa
    lista:

    <arquivo_do_livro> <ícone> <estante>

    ●   Todos os livros localizados em um diretório
        único, configurável.
    ●   Ícones de tamanho até 96x128 pixels,
        variável.
    ●   Cada “estante virtual” agrupa livros de
        assunto similar.
Aplicação com dual vídeo
Tatu (servidor web)
Tatu plugins

namespace eval myapp {}

proc myapp::service {conn parms} {
   tatu::log "******** myapp starting..."
   $conn outHeader 200 {Content-Type text/plain}
   $conn out "Example output of a simple service"
}


tatu::addRoute "/myapp" myapp::service

error "This is an error on purpose.nComment to
remove error msg."
Tatu plugins 2
proc route1 {conn parms} {
   tatu::log "*** method=[$conn reqCmd] conn=$conn
parms=$parms"
   $conn outHeader 200 {Content-Type text/plain}
   $conn out "Plain text output from a service
Parameters: $parms"
   return
}

    tatu::addRoute "/book/:title/author/:author" route1
Tatu plugins 3

proc route3 {conn parms} {
   $conn outHeader 200 {Content-Type text/plain}
   $conn out "method=[$conn reqCmd]n"
   $conn out "queryNames: [$conn queryNames]nQuery
variables:n"
   foreach var [$conn queryNames] {
      $conn out "$var --> [$conn queryData $var]n"
   }
   return
}

tatu::addRoute "/query" route3
Métodos da API
method outHeader {{status 200} {headers {}} {delayed 0}}
method out {s {bin 0}}
method queryNames {}
method queryData {name {multiple 0} {index -1}}
method reqCmd {}

--------------------------------------------

tatu::addRoute {route cmd {log 1}
    {protocols {http https}}}
tatu::log {msg {type "warn"}}

                                               Usado com várias “keys” iguais na query.
Arquitetura de aplicaçōes Web
       conteúdo
                                         estilo



HTML                             CSS




            Javascript

                         comportamento
Jquery.fileTree (javascript)

$('.filetree').fileTree({
   root: './',
   script: '/filetree'
},function(file){alert(file);});


 (*) O elemento .filetree (CSS class) poderá ser uma <div>
      no <html> da página:
     <div class="filetree"></div>

 (**) A rota /filetree irá disparar o script filetree::filetree.
Exemplo de web service
namespace eval filetree { }

proc filetree::filetree {conn params} {
    set dir [$conn queryData dir]
    tatu::log "filetree dir=$dir"
    set s {<ul class="jqueryFileTree">}
     foreach f [glob -directory $dir *] {
        if {![file isdirectory $f]} continue
           append s {<ul><li class="directory collapsed">}
           append s "<a href="#" rel="$f/">"
           append s "[file tail $f]</a></li></ul>" }
     foreach f [glob -directory $dir *] {
        if {[file isdirectory $f]} continue
           set ext [string range [file extension $f] 1 end]
           append s "<ul><li class="file">"
           append s "<a href=""#"" rel=""$f">[file tail $f]</a></li> }
           append s "</ul>"
    $conn outHeader 200 {Content-Type text/html}
    $conn out $s
}

tatu::addRoute "/filetree" filetree::filetree 0 {http}
Links interessantes
●
    http://pragana.net - Adventures in Linux
       Programming
●
    http://wiki.tcl.tk - Tcler's wiki
       (farta documentação!)
●
    http://www.tcl.tk/man/tcl/tutorial/tcltutorial.html
●
    http://www.tcl.tk - Tcl developer exchange
●
    http://wfr.tcl.tk - Tcler's wiki versão francesa
       (independente do original)
Perguntas




                ?
?
         ?
Palestra cbq

Palestra cbq

  • 1.
    Aplicações do Tcl e Starkits CBQ Recife - Outubro de 2012
  • 2.
    Porque usar scripts? ● Interatividade: não há o ciclo “edita-compila- testa”. ● Menos linhas de código (alto-nível). ● Melhor representação dos dados (no Tcl, por exemplo, tudo é string). ● Portabilidade. (Linux (e outros unices), Windows, Mac, mobile, embedded, ...)
  • 3.
    O que podemosfazer com Tcl? ● MITO: linguagens de script são muito lentas, não devem ser usadas em aplicações velozes (processamento de vídeo, por exemplo) ● REALIDADE: só uma pequena fração do código precisa ter velocidade extrema; scripts nos fornecem mais controle, flexibilidade e menos linhas de código.
  • 4.
    Sintaxe do Tcl ● Todos os comandos na forma: comando arg1 arg2 … Exemplos de comandos: set nome “Rildo Pragana” set numero 1234 puts $nome puts -nonewline “numero=$numero” ● Todos os tipos são equivalentes a strings (cadeia) de caracteres. ● Substituições: ● Variável  $variavel ● Comando [comando] ● Backslash  n t u00c7
  • 5.
    Sintaxe 2 ● Agrupando ítens: ● Com substituição: “cmd = $comandon data = [clock format $ck]” ● Sem substituição: {Nada disso é modificado: [teste], $} ● Expansão de argumentos: (evita uso de “eval”) set lsArgs {-l nota.txt} exec ls $lsArgs → não funciona eval exec ls $lsArgs → funciona mas expande tudo exec ls {*}$lsArgs → perfeito!
  • 6.
    Listas ● Exemplos de listas: ● set cores {azul amarelo vermelho branco} ● set lst { {12.37 N} {-1.567 W} 135 } ● Alguns comandos: ● list ?arg arg …? ● lindex list ?index …? ● lappend listVar ?value …? ● linsert list index element ?element …? ● Outros: lreplace, llength, lsearch, lsort, lset, lrepeat, lrange
  • 7.
    Arrays ● Variável com um índice (hash) Exemplos: data(agora) v(1) v(2) … posicao(12.5,23.7) ● Comando para manipular variáveis tipo array ● array names arrayName ?mode? ?pattern? ● array get arrayName ?pattern? ● array set arrayName list
  • 8.
    Dict (dicionário) ● Lista de pares key (chave), valor ● Comandos mais comuns: ● dict create ?key value …? ● dict get dictVal ?key …? ● dict set dictVariable key ?key …? value ● dict size dictValue ● dict keys dictValue ?globPattern? ● dict for {keyVar valueVar} dictValue body
  • 9.
    Criando subcomandos (ensemble) namespace eval ::counter { variable counter 0 namespace export get set incr namespace ensemble create } Utilização: counter set 35 proc ::counter::get {} { variable counter counter get return $counter counter incr } counter incr -2 set counter::counter proc ::counter::set {value} { variable counter return [::set counter $value] } proc ::counter::incr {{increment 1}} { variable counter return [::incr counter $increment] }
  • 10.
    Starkits ● Scripts e extensões encapsulados em um único arquivo (.kit), portável (Linux/Windows/Mac) ● Executável separado para cada plataforma: tclkit, tclkit.exe ● Diretório virtual. Pode conter scripts, bibliotecas (multiplas versões, uma para cada OS), documentação. Implementado no topo do banco de dados Metakit.
  • 11.
    Manipulando kits ● Utilitário sdx ● sdx qwrap programa.tcl – Gera um kit a partir do script fornecido ● sdx unwrap programa.kit – Expande o kit como o diretório programa.vfs ● sdx wrap programa.kit – Reempacota o kit usando o diretório programa.vfs – Opcionalmente, podemos usar -runtime tclkit para produzir um starpack (tudo em um só executável).
  • 12.
  • 13.
    Bibliotheca (2) ● Cada livro é representado por uma imagem (capa) de tamanho reduzido. ● Formatos dos arquivos (livros): pdf, djvu, chm, ps,...(outros podem ser suportados facilmente) ● Comandos para incluir novos livros, reorganizar as “estantes”, criar ícones para um livro, ou até para transferir o conteúdo (ssh) a partir de um servidor.
  • 14.
    Bibliotheca (3) ● Informações sobre livros armazenados numa lista: <arquivo_do_livro> <ícone> <estante> ● Todos os livros localizados em um diretório único, configurável. ● Ícones de tamanho até 96x128 pixels, variável. ● Cada “estante virtual” agrupa livros de assunto similar.
  • 15.
  • 16.
  • 17.
    Tatu plugins namespace evalmyapp {} proc myapp::service {conn parms} { tatu::log "******** myapp starting..." $conn outHeader 200 {Content-Type text/plain} $conn out "Example output of a simple service" } tatu::addRoute "/myapp" myapp::service error "This is an error on purpose.nComment to remove error msg."
  • 18.
    Tatu plugins 2 procroute1 {conn parms} { tatu::log "*** method=[$conn reqCmd] conn=$conn parms=$parms" $conn outHeader 200 {Content-Type text/plain} $conn out "Plain text output from a service Parameters: $parms" return } tatu::addRoute "/book/:title/author/:author" route1
  • 19.
    Tatu plugins 3 procroute3 {conn parms} { $conn outHeader 200 {Content-Type text/plain} $conn out "method=[$conn reqCmd]n" $conn out "queryNames: [$conn queryNames]nQuery variables:n" foreach var [$conn queryNames] { $conn out "$var --> [$conn queryData $var]n" } return } tatu::addRoute "/query" route3
  • 20.
    Métodos da API methodoutHeader {{status 200} {headers {}} {delayed 0}} method out {s {bin 0}} method queryNames {} method queryData {name {multiple 0} {index -1}} method reqCmd {} -------------------------------------------- tatu::addRoute {route cmd {log 1} {protocols {http https}}} tatu::log {msg {type "warn"}} Usado com várias “keys” iguais na query.
  • 21.
    Arquitetura de aplicaçōesWeb conteúdo estilo HTML CSS Javascript comportamento
  • 22.
    Jquery.fileTree (javascript) $('.filetree').fileTree({ root: './', script: '/filetree' },function(file){alert(file);}); (*) O elemento .filetree (CSS class) poderá ser uma <div> no <html> da página: <div class="filetree"></div> (**) A rota /filetree irá disparar o script filetree::filetree.
  • 23.
    Exemplo de webservice namespace eval filetree { } proc filetree::filetree {conn params} { set dir [$conn queryData dir] tatu::log "filetree dir=$dir" set s {<ul class="jqueryFileTree">} foreach f [glob -directory $dir *] { if {![file isdirectory $f]} continue append s {<ul><li class="directory collapsed">} append s "<a href="#" rel="$f/">" append s "[file tail $f]</a></li></ul>" } foreach f [glob -directory $dir *] { if {[file isdirectory $f]} continue set ext [string range [file extension $f] 1 end] append s "<ul><li class="file">" append s "<a href=""#"" rel=""$f">[file tail $f]</a></li> } append s "</ul>" $conn outHeader 200 {Content-Type text/html} $conn out $s } tatu::addRoute "/filetree" filetree::filetree 0 {http}
  • 24.
    Links interessantes ● http://pragana.net - Adventures in Linux Programming ● http://wiki.tcl.tk - Tcler's wiki (farta documentação!) ● http://www.tcl.tk/man/tcl/tutorial/tcltutorial.html ● http://www.tcl.tk - Tcl developer exchange ● http://wfr.tcl.tk - Tcler's wiki versão francesa (independente do original)
  • 25.