Question

I have an interface which looks something like:

interface IMyInterface {
    MyObject DoStuff(MyObject o);
}

I want to write the implementation of this interface in IronRuby, and return the object for later use.

But when I try to do something like

var code = @"
    class MyInterfaceImpl
        include IMyInterface

        def DoStuff(o)
            # Do some stuff with o
            return o
        end
    end

    MyInterfaceImpl.new";

Ruby.CreateEngine().Execute<IMyInterface>(code);

I get an error because it can't be cast to IMyInterface. Am I doing it wrong, or isn't it possible to do what I'm trying to do?

Was it helpful?

Solution

It isn't possible to implement a CLR interface in IronRuby and pass it back into CLR. 'MyInterfaceImpl' in your example is a Ruby class, not a CLR realization of 'IMyInterface'.

I stand corrected, per Jimmy Schementi's post.

You could however use IronRuby types as dynamic objects inside your .NET code:

    var engine = Ruby.CreateRuntime().GetEngine("rb");
    engine.Execute("/*your script goes here*/");

    dynamic rubyScope = engine.Runtime.Globals;
    dynamic myImplInstance = rubyScope.MyInterfaceImpl.@new();

    var input = //.. your parameter
    var myResult = myImplInstance.DoStuff(input );

OTHER TIPS

What you want to do is possible; IronRuby supports implementing interfaces by mixing the interface into the class.

Running your example I get this exception:

Unhandled Exception: System.MemberAccessException: uninitialized constant MyInte
rfaceImpl::IMyInterface

This does not mean the object cannot be cast to an IMyInterface, it just means the Ruby engine doesn't know what IMyInterface is. This is because you must tell IronRuby what assemblies to look up IMyInterface in, using ScriptRuntime.LoadAssembly. For example, to load the current assembly, you can do this:

ruby.Runtime.LoadAssembly(typeof(IMyInterface).Assembly);

The following shows you can invoke a Ruby-defined method from C# by invoking methods on an interface:

public class MyObject {
}

public interface IMyInterface {
    MyObject DoStuff(MyObject o);
}

public static class Program {
  public static void Main(string[] args) {
    var code = @"
    class MyInterfaceImpl
        include IMyInterface

        def DoStuff(o)
            # Do some stuff with o
            puts o
            return o
        end
    end

    MyInterfaceImpl.new";

    var ruby = IronRuby.Ruby.CreateEngine();
    ruby.Runtime.LoadAssembly(typeof(MyObject).Assembly);
    var obj = ruby.Execute<IMyInterface>(code);
    obj.DoStuff(new MyObject());
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top