Vitor Pamplona

Innovation on Vision: Imaging , Enhancement and Simulation

Interpretando Código em Tempo de Execução com Boo

Uma das features mais legais das linguagens de script é a interpretação de código em tempo de execução. Claro, nas outras linguagens isso também é possível, mas certamente é bem mais trabalhoso.

Hoje de manhã, resolvi ver como seria esta feature na linguagem Boo. Para quem não conhece, o Boo é uma linguagem de script estilo python para. Net, desenvolvido como hobbie pelo Rodrigo Bamboo, um brasileiro anormal, um ponto fora da curva. Como se integra a CLI, ele utiliza as bibliotecas disponíveis para Dot Net ou Mono e, por incrível que pareça, também acessa as bibliotecas Java. Recentemente o Rodrigo liberou um port do Boo que roda sobre a JVM ao invés do Mono ou do Dot Net. Para os viciados em IDEs, já existem plugins para Boo em Eclipse (boojay), MonoDevelop e SharpDevelop. Para conhecer a história da linguagem e o que levou o Rodrigo a criá-la, leia o manifesto.

A Boo possui diversas características interessantes como:

  • Duck Typing: Se algo caminha como um pato e faz quack como um pato então deve ser um pato.
  • Closures
  • Interpretador Interativo: Semelhante ao Python.
  • Slicing: Dado que L é uma lista com 40 elementos, você pode fazer: L [10:30].
  • Macros: Lembra as macros do C + +. É utilizado para simplificação de código.
  • String Interpolation: Manipulação de Strings semelhante ao velocity.
  • Generators: formas diferentes de escrever laços.

Boo se diferencia das outras linguagens de script por uma única característica: Facilidade para criar extensões. Ele tem um pipeline de compilação extensível, ou seja, você pode adicionar as suas características no compilador do boo. Engana-se quem pensa que isso é complicado, na verdade, em Boo é bem simples extender, tanto o compilador quanto a linguagem. Usar um interpretador em tempo de execução, então, nem se fala.

Como eu sou um cara bem prático, arrumei logo um objetivo para o meu primeiro teste com Boo: Criar uma tela na qual uma terceira pessoa pudesse adicionar as regras de negócio. Esse tipo de customização é um problema comum nos ERPs de propósito geral. Sempre que alguém implanta um ERP destes, surgem mudanças que devem ser feitas para aumentar a produtividade de um cliente específico. Exemplo, se ele lança muitas notas fiscais semalhantes, é interessante ter um botão para duplicar a nota atual, zerando apenas alguns campos. Se só existem pagamentos em dinheiro, é interessante deixar invisível os botões pagamento com Cheque, Cartão ou Vale Compras.

Desenvolvi a tela em questão com GTK + Mono + MonoDevelop no Ubuntu 7.10. Não sei como são os procedimentos de instalação destas bibliotecas no Windows. No meu caso, eu instalei o GTK, o GTK-Sharp, o Mono, o MonoDevelop com Boo e o compilador do Boo via apt-get, mas você pode usar o Synaptic, assim como usar SWT + Boojay e Eclipse se preferir.

Com o ambiente pronto, abra o MonoDevelop e crie um Novo Projeto Boo-GTK #. Selecione o GTK # Suport se você preferir criar a tela graficamente, eu criarei via programação mesmo. Depois de criado, o projeto já tem apenas 2 arquivos: Main.boo

// project created on 16/12/2007 at 15:20
import Gtk

Application.Init()
w = MyWindow("Window")
w.ShowAll()
Application.Run()

e o MyWindow.boo

import System
import Gtk

class MyWindow(Window):
def constructor(title as string):
super(title)
SetDefaultSize(400, 300)
DeleteEvent += { Application.Quit() }

Se você executar esse código aparecerá uma tela em branco.

Nós iremos criar uma tela semelhante a tela abaixo. É composta por duas abas, a primeira é onde está o formulário normal da aplicação, na segunda estará o código a ser executado quando o botão da primeira aba for pressionado. Como é para ser um exemplo simples, a função deste botão é apenas copiar o texto escrito no Edit e colocar no Label abaixo dele. O botão abaixo do texto na segunda aba irá compilar o código e setar a função para o botão Go da primeira aba.

 

Janela em Boo

 

Para construir essa tela, adicione ao construtor um simples código Boo + GTK-Sharp

    def constructor(title as string):
super(title)
SetDefaultSize(400, 300)
DeleteEvent += { Application.Quit() }

note = Notebook()

// First Tab: Frame
dynamicFrame = VBox()
note.Add(dynamicFrame)

hbox = HBox()

entry = Entry();
entry.Text = "Default value"
entry.SelectRegion(0, entry.Text.Length)
hbox.Add(entry)

go = Button("Go!")
hbox.Add(go)

result = Label();
result.Text = "Waiting..."

dynamicFrame.PackStart(hbox, false, true, 3)
dynamicFrame.Add(result)

// Second Tab: Source
dynamicSource = VBox()
note.Add(dynamicSource)

code = TextView()
code.Buffer.Text += "import System \n\n"
code.Buffer.Text += "def Button_Clicked(o, args as EventArgs):\n"
code.Buffer.Text += " result.Text = entry.Text \n"
code.Buffer.Text += "\n"
code.Buffer.Text += "go.Clicked += Button_Clicked \n"
code.Buffer.Text += "print \"Runned\" \n"
dynamicSource.Add(code)

refresh = Button("Refresh!")
dynamicSource.PackEnd(refresh, false, true, 0)

Add(note)

Depois disto basta rodar e você terá a sua tela. Repare que a Boo possui escopo orientado a indentação, por isso, dentro do construtor são necessários 2 tabs para cada linha.

Após, adicione um callback para o botão refresh , que deve interpretar o código.

    def Refresh_Button(o, args as EventArgs):
print "Evaluating"

E atribua o callback após a criação do refresh no construtor.

        refresh.Clicked += Refresh_Button 

Agora vem a mágica. Para compilar o que está na propriedade Text do code importe o Interpretador do Boo logo após o import da GTK:

import System
import Gtk
import Boo.Lang.Interpreter
...

Transforme as variáveis locais entry , result , code e go em atributos de classe

...
class MyWindow(Window):
entry as Entry
result as Label
code as TextView
go as Button

def constructor(title as string):
...

E, por fim, mande o programa interpretar o code.Buffer.Text

    def Refresh_Button(o, args as EventArgs):
print "Evaluating"
interpreter = InteractiveInterpreter()
interpreter.SetValue("go", go)
interpreter.SetValue("result", result)
interpreter.SetValue("entry", entry)
interpreter.Eval(code.Buffer.Text)
print "Evaluated"

Repare que é necessário setar as variáveis que serão utilizadas no Script. Caso contrário, ele não terá acesso a nenhuma variável do programa.

Pronto! Execute, clique no botão Go! e nada acontecerá, clique em Refresh! e você aplicará a regra de interface. Clicando em Go! novamente você verá a mágica. Alterando o texto para:

import System 

def Button_Clicked(o, args as EventArgs):
result.Text = "Valor: " + entry.Text
result.Angle += 20

go.Clicked += Button_Clicked
print "Runned"

ao clicar em Go! será exibido a sentença " Valor: " antes do texto do entry e o texto irá girar um ângulo de 20 graus anti-horário a cada clique. Fácil não é?

E tem mais. Se você quiser, pode colocar um code completion facilmente. Dê uma olhadinha no vídeo desta aplicação que fez um pouco mais do que eu.

Se precisar de ajuda para trabalhar com GTK, visite: http://www.go-mono.com/docs

Posted in Dec 4, 2008 by Vitor Pamplona - Edit - History

Showing Comments

Do manifesto:

" " " The guys who came up with “ public static void main ” were probably kidding, the
problem is that most people didn't get it was a joke. " " "

Bah, muito boa! Expressou o que eu sempre pensei de um jeito muito engraçado!

Achei bem legal a linguagem Boo. Já tinha ouvido falar, mas não tinha dado a devida atenção. Também não sabia que era uma linguagem brasileira!: - O

Gostei que tem macros, public / private (faz falta em Python) e a tipagem estática + duck combina deve combinar o melhor das duas. E, é claro, ver a sintaxe no estilo Python sendo usada em outras linguagens é bem legal.

Vai entrar na minha lista de linguagens a aprender (mas isso não quer dizer nada, tem umas que estão há anos na lista, hehehe)

- - Marcus Aurelius

- - Posted in Dec 20, 2007 by 200.96.95.178

Solicito, a atenção de vocês desenvolvedores, embora esteja, eu iniciando no mundo da programação ainda estou em crise com a linguagem, saio de uma e vou para outra;



Foi graças esse pula pula, que descobrir algos que diversas linguagens faltam, uma dessas coisas é o suporte para auxiliar os iniciantes no mundo dos Framework.
Com tais deficiências que encontrei em diversas linguagens de programação eu construir o meu projeto da minha própria linguagem.

Então peço ajuda de vocês, se puderem ainda, estou tentando aprender a programar mas os materiais didáticos não abordam completamente o certo ele causam uma confusão, no momento dinheiro não tenho se tivesse talvez já aprenderia a programar (Compraria materiais eficientes) mas, preciso que alguém me dê uma dica por qual linguagem devo começar de preferência as interpretadas
um bom exemplo desse é o Python.

para que se sentiu comovido envie um email para

mex.stell.com @ gmail.com

- - Mateus

- - Posted in Dec 10, 2012 by 187.73.48.130

Add New Comment

Your Name:


Write the code showed above on the text below.