image[2]

Esse é o terceiro post sobre como rodar Ruby no .Net, com IronRuby, e integrado ao C#. Estou usando o Visual Studio 2010 que é onde as coisas funcionam mais bem integradas, mas o primeiro post dá pra trabalhar ainda com o Visual Studio 2008. Os posts anteriores estão aqui:

  1. Rodando Ruby com C#: Parte 1
  2. Rodando Ruby com C#: Parte 2 – chamando uma classe Ruby no C#

No primeiro post eu mostrei como configurar o ambiente, e no post seguinte executamos código Ruby via .Net, inclusive passando parâmetros, e pegamos o retorno e utilizamos no C#. Utilizamos classes Ruby no C# normalmente com as novas capacidades dinâmicas do C# 4.

Neste post vou mostrar como fazer o contrário: tenho uma classe no C# que quero ser capaz de chamar a partir do Ruby. Isso é possível, vamos ver como.

Primeiro vou definir a classe que quero chamar do C#. Segue o mesmo molde das classes de antes, ela tem só um método que recebe dois parâmetros, e retorna uma string de acordo com os argumentos recebidos:

public class Teste
{
    public string Chamar(bool flag, string texto)
    {
        return flag ?
            texto + "sufixo" :
            texto;
    }
}

Quero chamar o método “Chamar” desta classe a partir do Ruby. Para poder fazer isso, preciso dizer pra ele referenciar minha dll de alguma forma. No Ruby, a maneira que você usa pra ele acessar outros arquivos Ruby é com a palavra chave “require”. Se você escrever “require MeuArquivo” o Ruby vai tentar encontrar o arquivo “MeuArquivo.rb” nos diretórios especificados na variável $LOAD_PATH, que normalmente inclui o diretório local (.). Pra saber quais são esses diretórios basta inspecionar a variável:

Console Ruby

No IronRuby, além de procurar arquivos .rb, o require vai procurar também dlls. Então você precisa acrescentar uma linha de require com o nome da sua DLL.

O código Ruby então fica assim:

require 'IronRubyNetFX4Test1'
IronRubyNetFX4Test1::Teste.new

Na primeira linha eu referencio meu assembly de testes, que é chamado IronRubyNetFX4Test1.dll. Na linha seguinte eu crio a classe Teste que havia especificado. Notem que os dois pontos duplos :: separaram a especificação do namespace e da classe. Como no Ruby a última linha sempre retorna o resultado, a classe Teste do C# está sendo retornada. O objeto retornado é entendido pelo C# como um objeto dinâmico, e pode ser chamado. Vejam o teste todo:

[TestMethod]
public void ConsigoCriarUmObjetoDotNetEChamarUmMetodoDinamicamenteUsandoONomeCompletoDoTipoEVariavelDinamica()
{
    var source = @"
        require 'IronRubyNetFX4Test1'
        IronRubyNetFX4Test1::Teste.new";

    var scriptSource = _defaultScriptEngine.CreateScriptSourceFromString(source);
    var teste = scriptSource.Execute();
    var resultado = teste.Chamar(true, "ttt");
    Assert.AreEqual("tttsufixo", resultado);
}

Mas eu poderia fazer um cast do retorno, já que o tipo retornado é um tipo .Net, e usá-lo normalmente:

[TestMethod]
public void ConsigoCriarUmObjetoDotNetEChamarUmMetodoDinamicamenteUsandoONomeCompletoDoTipoEVariavelEstatica()
{
    var source = @"
        require 'IronRubyNetFX4Test1'
        IronRubyNetFX4Test1::Teste.new";

    var scriptSource = _defaultScriptEngine.CreateScriptSourceFromString(source);
    var teste = (Teste)scriptSource.Execute();
    var resultado = teste.Chamar(true, "ttt");
    Assert.AreEqual("tttsufixo", resultado);
}

Faz mais sentido, se eu sei que o retorno é um tipo conhecido do C#.

O Ruby tem ainda uma palavra chave que faz a importação do namespace, semelhante ao “using” do C#, é o “include”. E nós podemos usá-la também:

[TestMethod]
public void ConsigoCriarUmObjetoDotNetEChamarUmMetodoDinamicamenteUsandoOInclude()
{
    var source = @"
        require 'IronRubyNetFX4Test1'
        include IronRubyNetFX4Test1
        Teste.new";
    var scriptSource = _defaultScriptEngine.CreateScriptSourceFromString(source);
    var teste = scriptSource.Execute();
    var resultado = teste.Chamar(true, "ttt");
    Assert.AreEqual("tttsufixo", resultado);
}

Com isso, fecho os exemplos do Ruby chamando o C#. Já conseguimos fazer código Ruby chamar C#, e vice-versa. A seguir vou mostrar alguns cenários onde penso que isso pode ser útil. Em breve.


Postado na(s) categoria(s) C# , IronRuby pelo Giovanni Bassi em 11 de janeiro de 2010 às 08:14 | Tags: , ,

Comentários


janeiro 11. 2010 09:17
Felipe Fujiy
Uma curiosidade, no ruby quando instancia um tipo do C#, é feita checagens em tempo de compilação/suporte do intellisense? Ou então depois de fazer um cast?

Abraços

http://blog.fujiy.net/http://blog.fujiy.net/


janeiro 11. 2010 11:41
Giovanni Bassi
Felipe, não tem nenhuma checagem em tempo de compilação no Ruby, simplesmente porque código Ruby não compila, é interpretado.
Isso significa que quando você trabalha com código Ruby, não tem Intelisense. E com dynamic no C# também não.
Quando você faz um cast para um objeto tipado do C#, aí tudo volta ao mundo estático que já estamos acostumados.

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

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

Eu vou ao TechEd Brasil 2010, e você?

MVP

MCPD

MCSD

.Net Magazine

Abaixo ao if!

Calendário

«  setembro 2010  »
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
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