Ruby for .NET Developers

Over last weekend I started building a website. The interesting thing about this project wasn’t really the website itself, but that I used Ruby and Ruby on Rails to build it. After spending just a few days with Ruby and Rails putting a site together, let’s just say I won’t be volunteering to touch ASP.NET again for a long time :)

There’s a list of guides on the official Ruby website for introductions from other languages (C++, Java), but none for .NET, so I figured I’d write one. Here are some of the differences between the .NET platform, runtime and languages and Ruby:

  • CLR applications are compiled and then JIT’ted, while Ruby is interpreted line-by-line.
  • null” is actually written as “nil“.
  • There’s no static type checking. If you call a method or property on a value, it’ll throw an exception if it doesn’t have that property/method, otherwise it will ”Just Work”. This is known as duck typing.
  • There are modules, which are like C# static classes, as well as regular classes.
  • You can add properties and methods to an object at runtime even if they didn’t already exist. It’s open to abuse, but there are many times where it comes in handy (check out instance_variables).
  • There are only two item container classes - hashtables and arrays. However the array is really more like a List<T>, because you can keep on adding stuff to it and it has all of the methods that that a List<T> has.
  • Everything evaluates to a value. Even a while loop returns a value (the number of things it looped over).
  • You have “symbols”. Symbols are pretty much a lightweight string, and start with a colon and don’t have quotes, for example: :customer_name. Symbols are usually used to refer to method or property names instead of using a regular string, just for the sake of convenience. Anywhere where you might use a symbol, you can pass a regular string.  
  • Parenthesis around function calls are optional. Method names can end with a “!” or a “?“, which helps to convey their meaning. For example, rather than an is_null method, you could have a method named “null?“. Methods with an exclamation mark mean they often modify the original object - for example, string.capitalize returns a new string, while string.capitalize! modifies the current string.
  • Strings are not immutable (or rather, they are mutable). That does mean you have to be a little more careful in how you deal with them, but it also has a few advantages. For example, if you call string.gsub! 5 times to replace five different patterns (similar to string.Replace in .NET), it won’t allocate 5 new string objects the way it does in .NET.
  • Ruby only ever uses one real native OS thread, but has the idea of “green-threads“. As the Ruby interpreter is analyzing and executing code, it actually does it’s own scheduling, doing what the operating system normally does.

By far the coolest thing about Ruby is blocks, in some languages known as closures, and similar to anonymous delegates in C#. Take the following C# code:

customers.ForEach(
    delegate (Customer c) {
        Console.WriteLine(c.Name)
    });

In Ruby, you could express that like this:

customers.each { |c| print c.Name }

Note how much easier the syntax is. However, you can also use do...end syntax in Ruby to write it like this:

customers.each do |c|
    print c.Name
end

This makes it look like any old if statement or for each loop in Ruby, meaning it looks like part of the application flow rather than something out of the ordinary like anonymous delegates in C#. In fact, most loops in Ruby are implemented using blocks - go figure!

One of the coolest uses of closures or blocks that I have seen so far is the Rake build tool. Rake is Ruby’s version of Make (think NAnt or MSBuild), and is designed for automating “tasks”. Let’s look at the definition of a Rake task:

task :build do
    print "Building..."
end

Notice the do...end syntax?

Let me explain: task is actually a method that defines a new build task that can be executed, :build is an argument (the name of the task), and then everything in the do...end is passed as the second argument. When that task is called from the command line, the do...end block is invoked. It’s really like passing an anoymous delegate, but it looks like a custom language.  

This kind of syntactic sugar is what makes Ruby application look like they were designed with a Domain Specific Language, when in fact they are just plain old Ruby. It’s a very lovely language to use; even without Rails, I plan to sneak the odd Ruby scripts into the Dev Centre when no-one is looking :)

For more information on Ruby, here are some links I found useful:

  1. Programming Ruby - The Pragmatic Programmer’s Guide
  2. To Ruby from C/C++
  3. Why’s Poignant Guide to Ruby
  4. The Ultimate Guide to Rake (save this for later)

Enjoy!

Technorati tags: , ,

10 Responses to “Ruby for .NET Developers”

  1. Great list.

  2. […] PaulStovell.NET » Ruby for .NET Developers Great compiled list of differences between the .NET platform, runtime and languages and Ruby. […]

  3. Links (6/14/2007)

    .NET Compile Xaml to C# (.cs) (via Jason Haley ) Ruby for .NET Developers A .Net Dev’s First Look At

  4. some tips:
    —————
    null? - you can ask everything if its nil?

    symbols - if you create 2 strings, “aa” and “aa”, then they have different object_id’s. but 2 symbols :aa and :aa have the same object_id

    if you call an nonexisting method, its name and params are passed to method_missing before raising an exception. so actually you can still handle this (its also used to create methods on the fly, mocks etc stuff).

    one of the big differences for me was that there no casting in ruby.

    thanks for the list!

  5. Thanks for those tanel, I knew you could dynamically handle methods that don’t exist but I didn’t realise it was done by missing_method. I have a long way to go, but Ruby just gets better and better :)

    Thanks for explaining the difference between symbols and strings as well. Symbols sound similar to the “string interning” done in .NET.

  6. […] necessarily mean that it is good for you. Paul Stovell recently posted up an article entitled Ruby for .NET Developers which does a really good job of pointing out some of the key features of developing on the […]

  7. nice work Paul!

  8. […] A cool use for extension methods and LINQ expressions. 18 06 2007 Yesterday I responded to Paul Stovell’s post about Ruby for .NET developers, in that post I showed how you could use the LINQ expression with the List<T> object’s […]

  9. Paul,

    Nice to see another .NET guy getting into Ruby (and Rails)! It certainly does make cross-browser internet sites easier to build, although for internal ASP.NET apps it is not as competitive (too easy to for most developers to build web apps like WinForms to want to change).

    I’d be interested to see what scripted tools you come up with for the Dev Centre - I haven’t yet mixed Ruby with my .NET work environment.

    Thanks,
    Angus

  10. […] example) or runtime were open enough to allow developers to create extensions like this easily. In Ruby with no additional extensions, I could just write code like […]

Leave a Reply