O Marcus Sá, acabou de ganhar o livro Desenvolvendo Aplicações com UML por escrever este tutorial:
DLS é uma maneira simular no ruby outra linguagem. Ou seja, uma sintaxe diferente para um problema em mente…
Por exemplo, digamos que existe algo que você faz diversas vezes… Como uma espécie de mapa… Eu desenvolvi esse código para o curso que estou fazendo na e – Genial, que por sinal está ótimo… Ai vai uma breve descrição…
Farei um mapa para chegar até a minha casa…
Mapa Minha Casa
- “caminho “Virar a direita”,” no Posto “
- caminho “Seguir reto”,” ate o Campo do Barnabé “
- caminho “Virar a esquerda”,” na Madeireira “
- distancia “quatro Kilometros”
- tempo “30 minutos”
Achei bem legal o tutorial dele, eu apenas faria algumas modificações no exemplo, mais ou menos assim:
class Mapa
#Inicialização da classe, recebe o nome do mapa e um bloco com os dados dele
def initialize(nome, &bloco)
#Atribui o nome do mapa
@nome = nome
#Atribui os dados do mapa
@dados = {
#Note que poderemos ter mais de uma instrução, estão criaremos um Hash
:instrucao => {},
# Os demais campos do bloco dados serão campos normais
:distancia => nil,
:tempo => nil
}
#Invoca o bloco como se o mesmo fosse parte de um instancia de objeto
instance_eval(&bloco)
end
def virar(direcao,onde)
caminho("virar a #{direcao}"," n(o/a) #{onde}")
end
def seguir(opcoes = {})
if opcoes[:ate]
caminho "seguir", "até #{opcoes[:ate]}"
elsif opcoes[:por]
caminho "seguir", "por #{opcoes[:por]}"
end
end
# Atribui os dados
def caminho(acao, instrucao)
@dados[:instrucao][acao] = instrucao
end
def distancia(distanciakm)
@dados[:distancia] = distanciakm
end
def tempo(tempomin)
@dados[:tempo] = tempomin
end
# Exibição dos dados
def to_s
resultado = ""
resultado << "Mapa #{@nome}\nCaminho:\n"
@dados[:instrucao].each do |ordem|
resultado << "\t - #{ordem}\n"
end
resultado << "Distancia: #{@dados[:distancia]}\n"
resultado << "Tempo: #{@dados[:tempo]}\n"
resultado
end
end
# Instancia a classe Mapa
def mapa(nome, &bloco)
Mapa.new(nome, &bloco)
end
# Monta o mapa "Minha Casa"
m = mapa "Minha Casa" do
virar :direita, "no posto"
seguir :ate => "o campo grande"
virar :esquerda, "madeireira"
seguir :por => "aproximadamente 15 kilometros"
virar :direita, "frente do bar do zé"
distancia "20 Kilometros"
tempo "30 minutos"
# Mostra o conteúdo da string resultado que é retorno de to_s
puts to_s
end
Percebam os métodos especializados novos que foram adicionados …
A idéia de uma DLS é que seja possível explicar facilmente utilizando jargões do domínio ao qual aquela DSL se aplica, por exemplo, para melhorar mais ainda este exemplo a utilização dele teria que ser mais ou menos assim:
# Monta o mapa "Minha Casa" m = mapa "Minha Casa" do virar :direita, "posto", 500.metros seguir :ate => "o campo grande", :por => 200.metros virar :esquerda, "madeireira" seguir :por => 15.kilometros virar :direita, "frente do bar do zé" # Mostra o conteúdo da string resultado que é retorno de to_s puts to_s end
Neste caso fora as referencias a locais, todo o resto seriam comandos da linguagem especifica para montagem de mapas, mas fora esta pequena alteração no exemplo, o tutorial ficou muito bom, o livro vai ser entregue na sexta feira no encontro dos nerds de RoR aqui de porto alegre
PS.: Espero que o Shoes veja isto aqui e diga que eu to falando besteira, assim eu aprendo um pouco mais sobre DSL
PS2.: Este foi o primeiro vou deixar assim, mas se vocês prestarem atenção, os tutoriais escritos para ganhar o livro, são para serem postados aqui neste blog, e não no do autor
Tags: Ruby
Opa, olha só, o primeiro vencedor fui eu! E o meu vai sair 100% de graça!!!!!
[Translate]
As alterações ficaram bem legais. Como rule of thumb tudo que não variar além de um intervalo deve ser ‘tokenizado’ (transformado em algo como os simbolos que você utilizou). Minhas DSLs estão muito baseadas em Strings e isso está me imcomodando bastante.
Outro ponto foi o que comentei no blog do Marcus sobre evitar instance_eval para não perder as closures.
[]s
[Translate]
eu pensei em remover o instance_eval, mas a única forma que consegui fazer isto sem utilizar módulos para declarar os métodos foi passando self como parâmetro para a closure, ai em vez de poder escrever: virar eu teria que escrever m.virar …
Claro que isto apenas para este exemplo, concordo que usando o instance_eval, integrar isto com um sistema de verdade seria quase impossível
[Translate]
Parabens pelo livro Marcus!
“A idéia de uma DLS é que seja possível explicar facilmente utilizando jargões do domínio ao qual aquela DSL se aplica”
Acho que isso está mais para uma Business Natural Language (BNL http://blog.jayfields.com/2006/11/bnl-common-pieces.html). Uma DLS é apenas uma linguagem focada em resolver um problema se ela vai usar ou não jargões é outra historia! =D
Tem um exemplo legal de uma DSL que fiz aqui:
http://forum.rubyonbr.org/forums/14/topics/698
[]s
[Translate]
Daniel, não concordo muito com o que tu escreveu …
Vamos seguir com o teu exemplo …
Os jargões para controlar o winamp neste caso são, play, stop, pause que é exatamente o que tu esta usando …
Agora se tu fosse seguir o exemplo original do Marcus, seria algo do tipo:
comando “play”
comando “stop”
neste segundo caso eu ja não concordo que isto fosse uma DSL, acho que o que gerou a confusão foi a palavra “jargão” …
Uma DSL tem que ser especifica e não genérica como o próprio nome diz
[Translate]
Atenção pessoal.. um site de Portugal está pagando em euros(quase 3x mais q em reais) pra quem estiver disposto a:
* Ler anúncios
* Visitar sites
* Clicar em banners
* Navegar na NET
* Ler e-mails
http://www.publipt.com/pages/index.php?refid=kennedypeixoto
[Translate]
É realmente jargões ai foi uma pegadinha. hehehe!
Mas será que o unico jeito de deixar uma linguagem especifica ao dominio é usando “jargões”? ;D
Se eu tiver uma linguagem prontinha para um dominio que resolve varios problemas nesse dominio e por exemplo for para realidade de outra cultura em que os jargões sejam outros mas os problemas continuam iguais. Será que essa linguagem é especifica ao dominio nesse caso? =O
[Translate]
Daniel, pelo menos pelo o que eu entendo por DSL, ela tem que fazer sentido para quem esta utilizando, por tanto uma DSL é especifica, sendo assim, uma DSL para envio de e-mail escrita em portugues, para um usuário que não fala portugues não é uma DSL pois aquelas palavras não fazem sentido algum …
Lógico que este conceito pode estar errado
[Translate]