[Ironruby-core] Accessing IronRuby method from C#

Robert Brotherus robert.brotherus at napa.fi
Tue Jan 22 11:19:52 EST 2008


Greetings to the mighty IronRuby experts from a humble developer! :-)

I am testing the latest CVS snapshot (v. 73, downloaded an hour ago) of
IronRuby.

We are evaluating IronRuby for possible usage in WPF project. 

First, I want to test a simple case of defining a method in Ruby and
calling the method later from C#.

Below I copy a test program that tries this in two ways (methods
AccessMethod1 and AccessMethod2). 
Both attempts fail with exceptions that are written as comments in the
code.

I understand that the DLR and IronRuby are in a flux at the moment but I
still suppose there must be some working way to perform such trivial
interop task...?

Thanks in advance!

Robert Brotherus
Software architect
Napa Ltd

---------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
using Ruby.Runtime;
using Ruby.Builtins;

namespace IronRubyTests
{
    class Program
    {
        private IScriptEnvironment _scriptRuntime;
        public IScriptEnvironment ScriptRuntime         { get { return
this._scriptRuntime; } }
        public IScriptEngine RubyEngine                 { get { return
ScriptRuntime.GetEngine(typeof(RubyContext)); } }
        public ObjectOperations Operations              { get { return
RubyEngine.Operations; } }
        public RubyExecutionContext ExecutionContext    { get { return
Ruby.IronRuby.GetExecutionContext(RubyEngine); } }
        public IAttributesCollection GlobalItems        { get { return
ExecutionContext.GlobalScope.Dict; } }

        delegate void TestDelegate();

        static void Main(string[] args)
        {
            new Program().RunAllTests();
        }

        public Program()
        {
            this._scriptRuntime = Ruby.IronRuby.CreateRuntime();
        }

        public void RunAllTests()
        {
            List<TestDelegate> tests = new List<TestDelegate> {
                new TestDelegate(SimpleTests), new
TestDelegate(AccessMethod1), new TestDelegate(AccessMethod2)
            };
            foreach (TestDelegate test in tests)
            {
                Console.WriteLine("================== EXECUTING: {0}
====================", test.Method.Name);
                try { test(); }
                catch (Exception ex) { Console.WriteLine(ex); }
            }
        }

        public IScriptScope ExecuteString(string code)
        {
            return ScriptRuntime.ExecuteSourceUnit(
                RubyEngine.CreateScriptSourceFromString(code)); 
        }

        public void SetGlobalVar(string varName, object value)
        {
 
ExecutionContext.GlobalVariables[SymbolTable.StringToId(varName)] =
value;
        }

        public object GetGlobalVar(string varName)
        {
            return
ExecutionContext.GlobalVariables[SymbolTable.StringToId(varName)];
        }

        public object GetGlobalConst(string name)
        {
            return
GlobalItems.SymbolAttributes[SymbolTable.StringToId(name)];
        }

        public void SimpleTests()
        {
            ExecuteString("puts 'RUBY SAYS HELLO'"); // OK
            SetGlobalVar("x", 666); // OK
            ExecuteString("$y=555"); // OK
            ExecuteString("puts \"ruby: $x = #{$x}\""); // OK
        }

        public void AccessMethod1()
        {
            // Following fails with System.MissingMethodException:
undefined local variable or method 'method' for main:Object
            ExecuteString(@"
                def sayHello 
                   puts 'Hello from method!' 
                end

                $m = method(:sayHello)
            ");

            // Get the method object:
            object m = GetGlobalVar("m");

            // Here call the method, etc.
        }

        public void AccessMethod2()
        {
            ExecuteString(@"
              module MyMethods
                def sayHello 
                   puts 'Hello from method!' 
                end
              end
            ");

            RubyModule myModule = (RubyModule)
GetGlobalConst("MyMethods"); // OK
            object sayHello = Operations.GetMember(myModule,
"sayHello"); // Fails at Assertion at
ActionBinber.UpdateSiteAndExecute()

            // Here call the method, etc.
        }

    } // class

} // namespace


-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20080122/e6007d0b/attachment-0001.html 


More information about the Ironruby-core mailing list