Tuesday, December 15, 2009

Hosting IronRuby in .Net applications - Part2

In last post of this series we have seen few examples of IronRuby. That is just a glimpse of IronRuby.
With this background we can take a look at integrating these snippets in a .Net application.

I would like to provide some basic introduction about Dynamic Language Runtime (DLR) and then present an example.

DLR Overview

DLR infrastructure provides solutions for different purposes which include

  1. port dynamic languages to .NET
  2. add dynamic features to existing language
  3. author libraries whose objects support dynamic operations
  4. employ (host) dynamic languages in applications and frameworks
But this post is oriented towards hosting scenarios only.

DLR is built on top of Common Language Runtime (CLR). Microsoft .Net framework is designed to support multiple programming languages on CLR. It provides common services like GC, JIT etc. for static languages like C#, VB.Net etc. The CTS and CLI infrastructure allows sharing libraries written in any language with any other language targeting CLR. And we rarely realize need to host CLR explicitly, as it is done automatically by various CLR executable modules due to modifications done to Portable Executable format.

DLR extends CLR with services required for dynamic languages like python, ruby. In similar lines it first extends type system to be dynamic. Then, incase of statically typed languages, meta data provides necessary relative virtual addresses at compile time for method invocations. These virtual pointers turn into realistic pointers during JIT compilation process and remain as is as long as execution engine is alive. This is not the case with dynamic languages which require a dynamic method dispatching mechanism. Also applications need to explicitly host Dynamic Runtime Engines. But DLR eases some effort here by providing a common hosting API for all dynamic languages targeting DLR. So if we summarize, key components of DLR would include

  1. dynamic type system
  2. dynamic method dispatching system
  3. common hosting API

Dynamic type system and dispatching system provide services for first three purposes mentioned at the beginning of ‘DLR Overview’. Common hosting API provide services for last purpose in that list.

Hosting Scenarios

As such there could be several scenarios in which DLR can be employed (hosted). Such scenarios include

  • executing a script in a given scope using default script-host
  • executing several scripts in multiple scopes using custom script-host
  • controlling on how to pre-compile and improve executing performance, an advanced scenario

This part of the series confines to first scenario in which one script is executed in a given scope.

Execution Overview

As mentioned above, this post is presenting the very basic mode of executing a script.
Steps involved in this process include

  • Create Script Engine for Ruby
  • Create Scope object from engine and set scope
  • Create code
  • Execute code within a given scope

Example

Following step by step procedure makes up a simple application to host IronRuby

  1. Start Visual Studio and create a new console application. Copy required
  2. Refer following dependent assemblies from ~\<Program Files>\IronRuby 0.9.2\bin
    IronRuby.dll
    IronRuby.Libraries.dll
    Microsoft.Dynamic.dll
    Microsoft.Scripting.Core.dll
    Microsoft.Scripting.dll
  3. Add following using statements
  4. using IronRuby;
    using Microsoft.Scripting.Hosting;
    using Microsoft.Scripting;

  5. Add following code in Main

  6. ScriptEngine engine;
    ScriptScope scope;

    String code;

    Int32 i1 = 20;
    Int32 i2 = 10;

    engine = Ruby.CreateEngine();
    scope = engine.CreateScope();

    scope.SetVariable("i1", i1);
    scope.SetVariable("i2", i2);

    code = @"def compareValues()
    return $i1 > $i2
    end

    $i1 = i1;
    $i2 = i2;

    comp = compareValues();

    puts comp";

    engine.Execute(code, scope);

    Console.WriteLine("Press any key to continue");
    Console.ReadLine();


  7. Build and run code.

If everything goes well you should see true on screen.


No comments: