IronShay

Ironing code, geek t-shirts and even presentations!

NAVIGATION - SEARCH

C# Recorder using IronRuby

[This post is the second in my series of IronRuby samples. Read the first one here]

The release of Visual Studio 2010 Beta 2 and IronRuby .Net 4.0 Beta 2 CTP has brought some AMAZING abilities to the .Net world like the dynamic keyword. This keyword is a revolutionary little thing. It takes everything you know about C# and throws it away – explicit types, locating syntax errors in compilation time, compiled code…

Sounds bad? well, it is just AWESOME!!! The dynamic keyword brings so much goodness to our beloved C# language, that if it was possible I would have hugged it and asked it to join my family.

Well, enough with the nonsense, let’s get down to business. IronRuby is Microsoft’s implementation of the Ruby language. It runs on top of the DLR and provides a seamless integration with .Net code. In short, it ROCKZZZZZ. This post is about IronRuby’s seamless integration with .Net and the ability to use the great power of Ruby inside C#.

The Ruby language has some very powerful metaprogramming abilities. One of those is the method_missing method. When you declare it in your class, every call to a method that doesn’t exist will be routed to it. You can then do whatever you want with the call – execute a different method, raise an exception, interpret the call somehow or just do whatever you want (jump in the air? do your little Irish dance thing?).

Another nice metaprogramming feature is the ability to send requests to objects by using the send method. The concept is very similar to C#’s reflection method – Invoke.

Now if we combine method_missing and send, we can create a class that saves calls and playbacks them upon request. I will call it… tam tam tam… Recorder:

 

class Recorder
  # Initialize an array that will save the calls
  def initialize
    @calls = []
  end
   
  # Save the calls to method_missing	
  def method_missing(name, *args, &block)
    @calls << [name, args, block]
  end

  # Playback the calls on a given object	
  def playback(obj)
    @calls.each do |name, args, block|
      obj.send name, *args, &block
    end
  end
end

 

I think this code is pretty straight forward, no special things here. With this class defined, we can record Ruby calls and playback them on Ruby objects:

 

# Record calls
rec = Recorder.new
rec.reverse!
rec.insert 2, "ABAB"
rec.delete! "A"

# Playback them on a real object
str = "Hello World"
rec.playback(str)
puts str # Prints "dlBBroW olleH" 

 

 

It is AWESOME, but the great thing about it is that with .Net 4.0 and the dynamic keyword, it is available in C# too!

To try the next code by yourself, first open Visual Studio 2010 Beta 2, create a new C# console application and add references to IronRuby.dll, IronRuby.Libraries.dll, Microsoft.Scripting.dll and Microsoft.Dynamic.dll (remember to use the CTP assemblies and not the regular IronRuby assemblies).

The following code loads the Ruby recorder class file (recorder.rb) to the C# environment, creates an instance of the Recorder class, records a few operations and playbacks them on .Net objects:

 

static void Main(string[] args) 
{      
  // Load the recorder IronRuby file
  var engine = IronRuby.Ruby.CreateEngine();
  engine.ExecuteFile("../../recorder.rb");
  dynamic ruby = engine.Runtime.Globals;

  // Initialize IronRuby's recorder class
  dynamic recorder = ruby.Recorder.@new();

  // Record
  recorder.Add(1);
  recorder.Add(2);

  // Playback on CLR's List object
  List<int> list = new List<int>();
  recorder.playback(list);

  // Print the results!
  foreach (var item in list)
  {
    Console.WriteLine(item);
  }

  // Record console printing
  recorder = ruby.Recorder.@new();
  recorder.Write("IronRuby");
  recorder.WriteLine(" and .Net 4.0");
  recorder.WriteLine("Rock!!!!!!!!!!");

  // Playback on console
  recorder.playback(Console.Out);
}


The output to the console will be:
1
2
IronRuby and .Net 4.0
Rock!!!!!!!!!!

Try it out and see the magic happens right in front of your very own eyes!

In my opinion, this joint venture is incredibly helpful and useful. I predict that as time goes by we will see more and more dynamic language code make its way to the conservative .Net world, enhancing it and adding it powerful abilities that it never has had before.

All the best,
Shay.

Share it: kick it on DotNetKicks.com Shout it



Comments (5) -

United States Kevin Radcliffe

Very nice and interesting use of dynamic. It really lowers the bar to entry in using dynamic languages from C#. Like for me, it sounds like you had done enough interop with C# previous to dynamic to really see the difference it makes. Thanks very much for posting!

Reply

Wow ! i could imagine some serious applications for this. Imagine what this could do for automated testing ....

Reply

Great post.

Reply

Indeed it's a great feature and congrats on your post , you managed to get the key parts very well organized and explained.

Reply

Another great IronRuby tutorial by you, thanks a bunch!

Reply

Pingbacks and trackbacks (9)+

Add comment