DCSIMG
November 2009 - Posts - IronShay

November 2009 - Posts

Executing IronPython Code from IronRuby

One of the advantages of the Dynamic Language Runtime (DLR) is the fact that it makes sharing code between the languages that are written on top of it (and on top of the CLR as well). Therefore, it is possible to share code between IronPython and IronRuby (and any other DLR language as well like IronScheme).

This means that IronPython libraries can be used from IronRuby code and vice versa. Ruby on Rails in Python? Django in Ruby? feels like the end of days, isn’t it? perhaps we should really start preparing to year 2012

In this post I’ll show you how to run simple IronPython code from IronRuby so you can take it and do whatever your imagination guides you to.

Assuming we have a demo.py IronPython file with the next content:

class MyPythonClass:
  def add(self, x, y):
    return x + y

welcome_message = "Hello from Python!"

 

To those of you who don’t know Python, the code  above declares a class named MyPythonClass with a single method named add that combines two numbers and return the result. It also contains a variable named welcome_message.

Note

Because executing Python code from IronRuby involves DLR services, methods that you call from IronRuby must have self as their first argument just like IronRuby-targeted C# methods have (if the method accepts no parameters, then it should have only the self argument). This argument contains the caller class instance.
This means that python code that should be executed by IronRuby should be modified to match the requirements.

After we have the python file in place we can use it from IronRuby. The key for doing so is loading the python file using the IronRuby.require method. This method is similar to the Kernel#require method but with a small difference – it returns the DLR scope object of the loaded script.  This enables you to call the script members via the scope, just like when you load a script manually via the DLR LoadFile method.

The next IronRuby is pretty straight-forward:

# Load the python file
python = IronRuby.require('demo.py')

# Get an instance of MyPythonClass
python_class = python.MyPythonClass
# Execute the add method (pay attention that there's no 
# need to pass the self parameter, this is done automatically)
puts python_class.add(1, 5)

# Get the python variable and print its value
puts python.welcome_message
# Set the python variable
python.welcome_message = "Hello from Ruby!"
# Print its new value
puts python.welcome_message

 

The output is:
6
Hello from Python!
Hello from Ruby!

Note that for this sample to run, you need IronRuby and IronPython installed on your machine, both compiled with the same Microsoft.Scripting project. I just compiled IronRuby’s and IronPython’s sources to make  it work.

In conclusion, the DLR opens a bunch of new and exciting possibilities specifically in the field of code sharing between dynamic languages and dynamic and static languages. Go ahead and try it, it’s magical!

All the best,
Shay.

kick it on DotNetKicks.com Shout it

Posted by shayf | with no comments

IronRuby Sample #3: Creating a DSL

[ This is part 3 of my IronRuby samples series. You can read the first post (Hello World) and the second post (C# Recorder using IronRuby) as well. ]

The Ruby language is very powerful in general, and in its metaprogramming abilities in particular. This time I’m going to demonstrate how you can take advantage of these abilities along with Ruby’s syntax capabilities in order to create a custom DSL (Domain Specific Language) in a matter of minutes. Pay attention that these features are not specific to IronRuby, they are a part of every implementation of the Ruby language.

Let’s start from the end this time. This is the code you will be able to write with my little DSL:

list = ShoppingList.new
list.buy 3.kilograms.of(Peanuts)
list.buy 100.grams.of(Cheese)
list.buy 2.kilograms.of(Snacks)
list.print

Running this will result in the next output to the console:

Please buy:
- 3000 grams of peanuts
- 100 grams of cheese
- 2000 grams of snacks

It’s a nice little DSL to manage your shopping lists with. But as much nice as it is, the more important fact is that you can write your custom DSLs in Ruby (and IronRuby of course) with ease and make your coding experience much more fluent.

How is it Written?

The code for this DSL contains 49 lines of code, including lots of comments… Again, writing DSLs in Ruby (and IronRuby) is very easy. All I needed for this DSL were two “special” techniques of Ruby – const_missing and monkey patching. These two together makes about all the magic of this DSL.

I’m not going to go through the code line by line. I added comments inside the code so I think it will pretty straight forward to read. Do not hesitate to comment or contact me directly if something is not clear enough.

the DSL code:

# ShoppingList class
class ShoppingList
  # Ruby's class constructor - initializes the shopping list array.
  def initialize
    @list = []
  end
  
  # The main method - gets an item and adds it to the array.
  def buy(item)
    @list << item
  end
  
  # Prints all items in the list in a user-friendly way.
  def print
    puts "Please buy:"
    @list.each do |item|
      puts "- #{item[:grams]} grams of #{item[:product].downcase}"
    end
  end
end

# Every call to an undefined constant will reach here.
# This allows to use Peanuts inside the DSL code without defining it
# so we can write 5.grams.of(Peanuts) instead of 5.grams.of("Peanuts")
def Object.const_missing(name)
  # Return the constant as a string
  name.to_s
end

# For the DSL, we need to add grams and kilograms methods to all integers in the application.
# In order to do that, I open the Fixnum class (which is Ruby's equivalent to C# Int32) and add
# the needed methods
class Fixnum
  # grams method will just return itself
  def grams
    self
  end
  
  # Because we save everything in grams, when the kilograms method is used, I'll return 
  # the current value * 1000.
  def kilograms
    self*1000
  end
  
  # The of method retrieves an object and returns a hash of the object and its gram amount.
  def of(product)
    {:product=>product, :grams=>self}
  end
end


All the best,
Shay.

Posted by shayf | with no comments
תגים:,

Just Released: IronRuby 0.9.2

We’re getting closer to V1.0!

Version 0.9.2 fixes 44 bugs (some of the irritating ones like the Rails' bug with :default_url_options and the bug that prevented the RSS standard library from running).
The biggest announcement in the 0.9.2 version, in my opinion, is that IronRuby now has an MSI-based installer for Windows! no need to extract a zip file and do everything yourself anymore.

Download it from: http://ironruby.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=33693#DownloadId=90621
0.9.2 release notes: http://rubyforge.org/frs/shownotes.php?release_id=41087

Good times,
Shay.

Posted by shayf | with no comments
תגים:,

My Presentation at Web Developers Community – Riding IronRuby on Rails

Yesterday I had the honor to present IronRuby and Ruby on Rails to the Israeli web developers community.

Thanks all for coming! I had a great time!

The demo and presentation can be downloaded from here:

I also add here the list of resources to get you started with IronRuby and Ruby on Rails:

Lastly, if you have any question, request, recommendation or whatever, don’t hesitate to contact me through the contact form or twitter.

Thanks,
Shay.