IronRuby as a scripting language in .NET
Asked Answered
P

1

8

I want to use IronRuby as a scripting language (as Lua, for example) in my .NET project. For example, I want to be able to subscribe from a Ruby script to specific events, fired in the host application, and call Ruby methods from it.

I'm using this code for instantiating the IronRuby engine:

Dim engine = Ruby.CreateEngine()
Dim source = engine.CreateScriptSourceFromFile("index.rb").Compile()
' Execute it
source.Execute()

Supposing index.rb contains:

subscribe("ButtonClick", handler)
def handler
   puts "Hello there"
end

How do I:

  1. Make C# method Subscribe (defined in host application) visible from index.rb?
  2. Invoke later handler method from the host application?
Plenum answered 27/5, 2010 at 13:5 Comment(0)
A
7

You can just use .NET events and subscribe to them within your IronRuby code. For example, if you have the next event in your C# code:

public class Demo
{
    public event EventHandler SomeEvent;
}

Then in IronRuby you can subscribe to it as follows:

d = Demo.new
d.some_event do |sender, args|
    puts "Hello there"
end

To make your .NET class available within your Ruby code, use a ScriptScope and add your class (this) as a variable and access it from within your Ruby code:

ScriptScope scope = runtime.CreateScope();
scope.SetVariable("my_class",this);
source.Execute(scope);

And then from Ruby:

self.my_class.some_event do |sender, args|
    puts "Hello there"
end

To have the Demo class available within the Ruby code so you can initialize it (Demo.new), you need to make the assembly "discoverable" by IronRuby. If the assembly is not in the GAC then add the assembly directory to IronRuby's search paths:

var searchPaths = engine.GetSearchPaths();
searchPaths.Add(@"C:\My\Assembly\Path");
engine.SetSearchPaths(searchPaths);

Then in your IronRuby code you can require the assembly, for example: require "DemoAssembly.dll" and then just use it however you want.

Angle answered 27/5, 2010 at 15:2 Comment(3)
Thank you a lot. But 1 question remains. How to make available Demo class (not instance of it) within ruby code in such way that we would be able to instantiate it? For example: d = Demo.newPlenum
Added the answer to the body of the original answer above.Angle
With the latest IronRuby (1.13, I believe), you get a fixed-sized collection back for searchPaths, which throws an exception if you try to add to it. You need to create your own collection instead and copy over the values.Dimerous

© 2022 - 2024 — McMap. All rights reserved.