IronRuby

Agora o C# traz diversas características dinâmicas, na sua versão 4. Falei semana passada como usar uma delas semana passada, com um leitor de XML dinâmico. Além disso, dá pra fazer diversos outros malabarismos com C# 4 e o dinamismo. Já falei disso aqui, aqui, aqui e aqui.

Mas tem uma coisa que não dá pra fazer ainda de maneira muito simples, que é compilar código C# dinamicamente. Até dá pra fazer, mas dá um trabalho violento. Você tem que usar as classes do compilador do C# disponível em Microsoft.CSharp, como a CSharpCodeCompiler, e fazer todo o trabalho de referências, usings, namespaces, e dá um trabalhão que simplesmente não se paga.

O problema vem do fato de o C# não ser uma linguagem que nasceu para ser compilada dinamicamente, aberta desta forma, apesar de estar caminhando para isso. O ideal seria trabalhar uma linguagem que funciona melhor com scripts, mais dinâmica, como o VB. Infelizmente com VB dá o mesmo trabalhão, já que ele é irmão (quase siamês) do C#. Isso não é mais um problema: o .Net agora tem uma linguagem mais adaptada para isso, que é o IronRuby, implementação de Ruby para rodar nativamente no runtime do .Net, assim como o JRuby é a implementação do Ruby para o runtime do Java.

O IronRuby está em versão release candidate e já compila quase toda a especificação do Ruby, rodando os principais frameworks de Ruby, como o Rails (um MVC para web) e o RSpec (framework de BDD). Você pode pegar a versão que funciona com o .Net 3.5, que é o RC1, aqui. Essa versão é numerada como 0.9.3. A versão que vou usar neste post é a 0.9.1, a que tem como o .Net framework 4 Beta 2 (fique atento, há uma versão 0.9.1 que foca no .Net 3.5 também):

Versão do IronRuby

Não vou ficar explicando aqui a sintaxe do Ruby, que é super simples, e tenho certeza que vocês, que gostam de ponto e vírgula e chaves, vão entender. Pra quem quiser ver mais de perto dê uma olhada no tutorial oficial aqui. Eu gosto muito deste tutorial também, e ele é bem mais direto que o oficial.

Vamos ver o que podemos fazer com o Ruby integrado no .Net. Pra começar, baixe a versão que apontei, a que compila com o .Net 4, e baixe, se ainda não baixou (não??), o VS 2010 Beta 2.

Descompacte o zip em C:\ruby. Seu diretório deve ficar assim:

Diretório do ruby 

Não invente de colocar no D:, não invente de colocar debaixo de MyDocuments, ou em qualquer outro lugar. A instalação padrão do Ruby é no c:\ruby, e o Ruby é sensível. Amanhã se você quiser se integrar com a versão original do Ruby, feita em C (chamada de MRI), você vai ter problemas se o IR não estiver neste diretório. Não que não seja impossível colocar em outro lugar, mas se você não gosta de dor de cabeça, acredite em mim, e coloque ele lá, ok? Todos os exemplos do mundo de Ruby em Windows assumem que ele está lá.

Crie um projeto de testes com C# no Visual Studio 2010. Sim, testes. Porque você quer testar o IronRuby, lembra? Nós não testamos com projeto de console, ou Winforms, ou WPF, ou ASP.Net, nós testamos com projetos de testes automatizados, pra ter feedback constante e rápido se fizemos alguma coisa errada. Lembre-se disso, vamos em frente.

Referencie as seguintes dlls do IronRuby e do DLR que vão estar em c:\ruby\bin:

  1. IronRuby.dll
  2. IronRuby.Libraries.dll
  3. Microsoft.Dynamic.dll
  4. Microsoft.Scripting.dll

Em tempo, DLR é o que dá suporte às linguagens dinâmicas e agora faz parte do .Net Framework. O código é aberto e está no Codeplex.

Referencie também Microsoft.CSharp.dll, que deve estar nas suas referências de DLLs .Net. Ele é o assembly que permite usar a palavra chave dynamic, e fornece a infraestrutura de contato com a DLR, entre outras coisas. (Estou esperando desde o Beta 1 essa DLL sumir para dentro do BCL, ou do CLR, mas até agora nada…)

Pronto, infra resolvida. Agora basta fazer os testes.

Crie uma classe de testes, e crie a inicialização do contexto, que basicamente vai consistir em criar o runtime que vai rodar o Ruby. É código padrão, vai ser praticamente sempre igual em toda aplicação. Basicamente a inicialização cria um ScriptRuntime, que define o ambiente de scripting, e então, a partir dele, cria um ScriptEngine, que é quem executa nosso código fonte Ruby. O resto é detalhe. Criei um ScriptEngine estático, que será o padrão, usado por todos os testes. Precisando, podemos criar outro a partir do runtime, se fosse o caso. Ficou assim:

[TestClass]
public class Dado_Um_Contexto_Ruby
{

    private static ScriptRuntime _scriptRuntime;
    private static ScriptEngine _defaultScriptEngine;

    [ClassInitialize]
    public static void E_Um_ScriptRuntime_e_ScripEngine_Padrao_Inicializados(TestContext testContext)
    {
        CriarScriptRuntimeEEnginePadrao();
    }

    public static void CriarScriptRuntimeEEnginePadrao()
    {
        var setup = new ScriptRuntimeSetup();
        setup.LanguageSetups.Add(
            new LanguageSetup(
                "IronRuby.Runtime.RubyContext, IronRuby",
                "IronRuby 1.0",
                new[] { "IronRuby", "Ruby", "rb" },
                new[] { ".rb" }));
        _scriptRuntime = ScriptRuntime.CreateRemote(AppDomain.CurrentDomain, setup);
        _defaultScriptEngine = _scriptRuntime.GetEngine("Ruby");
    }
} 

Com isso, precisamos criar algum código fonte Ruby que execute. Se você abrir a console do IronRuby, disponível no executável c:\ruby\bin\ir.exe, vai poder digitar 1+2 e digitar enter. Vai dar o resultado, assim:

Console do IronRuby

Essa é a instrução mais simples do mundo, uma soma simples.

Que tal testar esse essa instrução? Fica assim:

[TestMethod]
public void Consigo_Somar()
{
    var source = "1 + 2";
    var scriptSource = _scriptEngine.CreateScriptSourceFromString(source);
    var resultado = (int)scriptSource.Execute();
    Assert.AreEqual(3, resultado);
}

Mais simples impossível! Na primeira linha criamos o complicadíssimo fonte, “1 + 2”, que é nosso código Ruby (depois vamos ver códigos mais interessantes, mas esse serve por enquanto). Na segunda linha chamamos o método “CreateScriptSourceFromString” no ScriptEngine e passamos nosso código fonte. Depois executamos, pegamos o resultado e comparamos com o esperado. Rode o teste, vai passar.

Esse é o básico. Nos próximos posts eu vou mostrar pra vocês como criar, com Ruby, um objeto a partir de uma classe definida no próprio Ruby e devolvê-la para o C# manipular, como criar um objeto a partir de uma classe definida em C# e usar ela no Ruby e devolver pro C#, e como chamar métodos de C# para Ruby e vice-versa.

Em tempo, todo esse exemplo rodaria no C# 3. A partir do próximo não vai rodar mais.
E se você gostou do Ruby, e está sentindo falta de uma IDE para te ajudar, dê uma olhada na RubyMine da JetBrains, que é a empresa que faz o Resharper. Já vi o Uncle Bob dizendo que usa, e o Brian Marick, do manifesto ágil, com quem pareei no Ágiles 2009, também usa. Eu tenho usado, e, apesar de não ser um Visual Studio (longe disso), é melhor que o Notepad, ou seus amigos anabolizados como Notepad++, Textmate, etc (que continuam mirrados).

Gostaria de saber se vocês se interessam pelo assunto, ou se encerro ele mais cedo por falta de interesse. Garanto que vou chegar em uma aplicação viável de negócio, mas só mais para o final…


Postado na(s) categoria(s) C# , IronRuby pelo Giovanni Bassi em 14 de dezembro de 2009 às 08:16 | Tags: , ,

Comentários


Brazil Gerson Dias
dezembro 14. 2009 09:24
Gerson Dias
Realmente o tema é bem interessante!

no site


Brazil Alessandro de Souza
dezembro 14. 2009 11:12
Alessandro de Souza
Interessantíssimo.
Imagino o seguinte: em um sistema qualquer que envolva fórmulas complexas, poderíamos deixar o próprio usuário definir suas fórmulas, ensinando ela a digitar uma script correta. Depois nosso sistema compila/excuta tal script com o resultado esperado pelo cliente. Este exemplo é apenas apenas uma suposição, porém, esta tecnologia tem um potencial muito grande de customização pelo próprio usuário, imagino eu.

no site


dezembro 14. 2009 16:56
Giovanni Bassi
Alessandro, exatamente! Você pegou a idéia. Vou chegar lá nos próximos.

http://unplugged.giggio.net/http://unplugged.giggio.net/


dezembro 15. 2009 00:22
Leonardo Neves
Continua sim Giggio, hehehehe

Em tempo: também estou usando o RubyMine e, de longe, é o mais bacana pra nós que estamos habituados a IDE's realmente produtivas como o Visual Studio.

http://blog.lneves.net/http://blog.lneves.net/


dezembro 15. 2009 09:41
Jarbas
Muito legal se você continuar com  esse assunto Giovanni. Desde o início deste ano Ruby começou a fazer muito barulho, e desde lá venho estudando aos poucos essa poderosa Linguagem. Se for de seu interesse, um assunto bem bacana é metaprogramação, com ruby então... hehehe!

Abraços

http://www.jsegundo.com.br/http://www.jsegundo.com.br/


Brazil Luiz Correa
dezembro 15. 2009 09:43
Luiz Correa
Muito interessante, e aos poucos, gostaria tb de ver mais cenários onde Ruby seria mais indicado do que C# no mundo real...

no site


dezembro 15. 2009 21:43
Rafael Noronha
Fala Giggio,

Acredito que este é o momento certo para a comunidade começar a olhar com carinho para o IronRuby.

Ruby é uma linguagem muito elegante, e pode oferecer ganhos de produtividade pelo fato de ser interpretada.

Rodando sob os runtimes de Java e .NET, acredito na tendência da linguagem ganhar força em cenários corporativos, não limitando-se mais ao cenário das Startups.

http://rafanoronha.net/http://rafanoronha.net/


dezembro 16. 2009 10:03
pingback
Pingback from pabloidz.wordpress.com

links for 2009-12-16 « pabloidz

http://pabloidz.wordpress.com/2009/12/16/links-for-2009-12-16/http://pabloidz.wordpress.com/2009/12/16/links-for-2009-12-16/

Comentar


(Vai mostrar seu Gravatar)

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading



Quem é Giovanni Bassi

Giovanni Bassi Sou uma pessoa apaixonada por tecnologia e especificamente por .Net. Sou consultor independente especialista em .Net, focado em arquitetura e melhores práticas. Tenho dezenas de artigos publicados na .Net Magazine, revista da qual sou editor técnico. Ministro palestras e cursos de vez em quando, e quando dá tempo eu respiro um pouco. Mais detalhes nesta página.

Busca

Selos

MVP

MCPD

MCSD

.Net Magazine

Abaixo ao if!

Calendário

«  março 2010  »
seteququsedo
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234
Ver detalhamento de posts no calendário

Blogs interessantes

    OPMLDownload OPML file

    Postagens recentes

    Comentários recentes

    Disclaimer / Aviso
    As opiniões colocadas neste blog são minhas e pessoais e não expressam necessariamente as opiniões de meus empregadores, pareceiros e amigos. Da mesma forma, os comentários feitos por leitores do blog não expressam a minha opinião.

    © Copyright 2010 .Net Unplugged
    Log in