IronRuby scripting in C#: invoking class method/function

332 Views Asked by At

I am trying to use IronRuby for some simple scripting in a C# application. I am trying to invoke a class method "execute" on class "Script" via the scripting engine, but it is simply not working. I have tried several methods and none seem to invoke the method.

This is my test Ruby code:

class Script
    def execute(input, parameter)
        return "test"
    end
end

Now I first want to check if the Script class exists, if it has the execute method, and if that method accepts exactly two parameters. This seems to work fine:

var engine = IronRuby.Ruby.CreateEngine();
var scope = engine.CreateScope();
var src = engine.CreateScriptSourceFromString(sourceCodeString, SourceCodeKind.Statements);
var compiled = src.Compile();
compiled.Execute(scope);

object rubyClass;
if (engine.Runtime.Globals.TryGetVariable("Script", out rubyClass))
{
    RubyClass instance = engine.Runtime.Globals.GetVariable("Script");

    var method = instance.GetMethod("execute");
    var param = method.GetRubyParameterArray();

    if (param.Count == 2)
    {
        // OK, try to execute (see below)
    }
}

It will only continue if the class and method are there with two parameters, great.

Now to execute the method I have found three possible ways, none of them work!

(1) Use dynamic to create an instance of the Script class and invoke the method. Source: Calling IronRuby from C# with a delegate

dynamic ruby = engine.Runtime.Globals;
dynamic script = ruby.Script.@new();
return script.execute("a", "b");

When executing the second line, the following exception occurs: Method not found: 'Microsoft.Scripting.Actions.Calls.OverloadInfo[] Microsoft.Scripting.Actions.Calls.ReflectionOverloadInfo.CreateArray(System.Reflection.MemberInfo[])'.

(2) Using engine.Operations.CreateInstance and dynamic:

object rubyClass = engine.Runtime.Globals.GetVariable("Script");
dynamic instance = engine.Operations.CreateInstance(rubyClass);
return instance.execute("a", "b");

Result is the same exception as (1) on second line.

(3) Using engine.Operations.Invoke:

return engine.Operations.Invoke(rubyClass, "execute", "a", "b")

Another exception: undefined method 'execute' for Script:Class

I'm at a loss. This last attempt (3) is extremely similar (if not exactly the same) as what I'm using for IronPython, where it works just fine.

Is there some problem with my Ruby code? I'm not that familiar with Ruby but this simple test class should not pose any problems surely?

1

There are 1 best solutions below

0
On

I found the answer myself here.

I needed to add the following before my Ruby script:

class System::Object
  def initialize
  end
end