How to fire IronRuby Method from C#

Hi,

I am returning an IronRuby object to C#. It is returned as a RubyClass
object. I can debug and see that it also has greet() method attached to
it but I am having difficulty in calling the greet() method from C#.
Here is the code.

var scriptingRuntime = IronRuby.Ruby.CreateRuntime();
var engine = scriptingRuntime.GetEngine(“rb”);

        RubyObject rubyPerson = ((RubyObject)engine.Execute(@"
        class Person

        def greet()
        puts 'hello world'
        end

        end

        def getPerson()
        return Person.new
        end

        getPerson()
        "));

        RubyClass rubyPersonClass = rubyPerson.ImmediateClass;

var operations = engine.CreateOperations();
operations.InvokeMember(rubyPerson, “greet”);

ironrubymvc/IronRubyMvc/Core/RubyEngine.cs at ef59166eb4e5e6b06b9d90abf95d637c2126e5ed · casualjim/ironrubymvc · GitHub

Met vriendelijke groeten - Best regards - Salutations
Ivan Porto C.
Blog: http://flanders.co.nz
Twitter: http://twitter.com/casualjim
Author of IronRuby in Action (http://manning.com/carrero)

Awesome thanks!

This should work:

var engine = IronRuby.Ruby.CreateEngine();

engine.Execute(@"
class Person
def greet()
puts ‘hello world’
end
end
");

object personClass = engine.Runtime.Globals.GetVariable(“Person”);
object person = engine.ObjectOperations.CreateInstance(personClass);
engine.ObjectOperations.InvokeMember(person, “greet”);

Tomas

Thanks Tom!

I wonder why dynamic type variable in C# 4.0 is not able to translate
the RubyClass and trigger the greet() method.

If this is C# 4 (as you’ve suggested in another email), you should be
able to say

object personClass = engine.Runtime.Globals.GetVariable(“Person”);
dynamic person = engine.ObjectOperations.CreateInstance(personClass);
person.greet();

Is there any special way for calling the ExecuteFile method:

engine.ExecuteFile(“hello.rb”,engine.CreateScope());

And here is the hello.rb file:

class Person
def greet()
puts ‘hello world’
end

        end

        def getPerson()

        return Person.new

        end

        getPerson()

Awesome!

I will try it out!

Yes, sorry, you’re right – it’s Engine.Operations (but the name of the
class is “ObjectOperations”).

The error message tells you exactly what you need to do! Make sure
you’ve added references to Microsoft.CSharp.dll and System.Core.dll to
your project.

Curt H. wrote:

Yes, sorry, you’re right – it’s Engine.Operations (but the name of the
class is “ObjectOperations”).

The error message tells you exactly what you need to do! Make sure
you’ve added references to Microsoft.CSharp.dll and System.Core.dll to
your project.

The error is now gone! but I got the new error which says:

RubyObject does not contain the definition for greet!

object personClass = engine.Runtime.Globals.GetVariable(“Person”);
dynamic person =
engine.Operations.CreateInstance(personClass);

        person.greet();

Odd. It works for me. Here’s my complete code:

namespace ConsoleApplication2 {
class Program {
static void Main(string[] args) {
var engine = IronRuby.Ruby.CreateEngine();

        engine.Execute(@"

class Person
def greet()
puts ‘hello world’
end
end
");

        object personClass = 

engine.Runtime.Globals.GetVariable(“Person”);
dynamic person =
engine.Operations.CreateInstance(personClass);
person.greet();
System.Console.ReadLine();
}
}
}

Curt H. wrote:

If this is C# 4 (as you’ve suggested in another email), you should be
able to say

object personClass = engine.Runtime.Globals.GetVariable(“Person”);
dynamic person = engine.ObjectOperations.CreateInstance(personClass);
person.greet();

I tried and it did not work out.

First engine does not have ObjectOperations. There is engine.Operations
which I used but I get the error when doing person.greet().

Error 5 Missing compiler required member
‘Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder…ctor’
ConsoleApplication1

Error 73 One or more types required to compile a dynamic expression
cannot be found. Are you missing references to Microsoft.CSharp.dll and
System.Core.dll? C:\Documents and Settings\AzamSharp\My
Documents\Visual Studio
10\Projects\testvs2010\ConsoleApplication1\Program.cs 80 13
ConsoleApplication1

This is very strange! I copy pasted your code and it is giving me
compile time errors:

Here is the code:

var rubyPerson = (engine.Execute(@"

       require 'open-uri'

       class Person


       def greet()
       puts 'hello world'
       end

       end

      Person.new()

        "));

       object personClass = 

engine.Runtime.Globals.GetVariable(“Person”);
dynamic person =
engine.Operations.CreateInstance(personClass);

       person.greet();

And here is the error:

Error 1 Missing compiler required member
‘Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder…ctor’
ConsoleApplication1

Error 61 One or more types required to compile a dynamic expression
cannot be found. Are you missing references to Microsoft.CSharp.dll and
System.Core.dll? C:\Documents and Settings\AzamSharp\My
Documents\Visual Studio
10\Projects\testvs2010\ConsoleApplication1\Program.cs 56 12
ConsoleApplication1

I have already added references to both the dll libraries.

Are you sure you have the appropriate version of IronRuby?
There is a special build just for .NET 4.0.
I was getting an error like the one you are until I used the .NET 4.0
build here:

http://ironruby.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=27606

Mohammad A. wrote:

This is very strange! I copy pasted your code and it is giving me
compile time errors:

Error 1 Missing compiler required member
‘Microsoft.CSharp.RuntimeBinder.CSharpBinaryOperationBinder…ctor’
ConsoleApplication1

Error 61 One or more types required to compile a dynamic expression
cannot be found. Are you missing references to Microsoft.CSharp.dll and
System.Core.dll? C:\Documents and Settings\AzamSharp\My
Documents\Visual Studio
10\Projects\testvs2010\ConsoleApplication1\Program.cs 56 12
ConsoleApplication1

I have already added references to both the dll libraries.

Yup! that did the trick! Thanks a million :slight_smile: