Learning Ruby via IronRuby and C# Part 1

Click here to view the entire IronRuby via C# series

In a previous post I explained how to get Iron Ruby up and running and then in another post I explained how to run an app in IronRuby. If you haven’t checked those out, then go do so!

So, if you are like many C# developers you have probably been hearing a lot recently about dynamic languages like Ruby and Python. And most likely, if you are a web developer, you have used a dynamic language. And by that I am talking about Javascript. So, if Javascript is a dynamic language you may be wondering what the big deal is. If you are like many C# developers, it is likely that you aren’t a fan of Javascript. And there are certainly many reasons for this, but I think that they are mostly because of differing implementations across browsers, and the fact that the programming paradigm is so different from what we are used to.

Ruby doesn’t have these problems. Ruby has a standard implementation which IronRuby is aiming at matching and Ruby operates in similar object oriented fashion that C# does as well. Hopefully in this series I am going to show you how to take some of your C# skills and show you how those can translate into Ruby. At the same time I hope you’ll see the power of Ruby and where Ruby might fit into your toolset.

Also, I am not a Ruby expert and I want you to know that this is going to be a learning experience for me as well as for you. If I do something poorly or do something completely wrong, then please feel free to call me out and I’ll get it fixed!

Before we start, what does it mean for a language to be dynamic? A dynamic language is generally just a language that runs in an interpreted environment, and does most things at runtime that static languages do at compile time. Because of this, the program is generally free to modify itself by running. Most people refer to this ability as Metaprogramming. Now, calling a language dynamic may be a little fuzzy, but I think that you’ll start to understand a bit better as we delve deeper into Ruby.

But let us first start off with the basics. And you really can’t get any more simple than variables. In C# a local variable declaration looks like this:

int count = 1;

You have the type, identifier, and then the value. In Ruby you just have this:

count = 1

As you can see, it is completely missing any type information. This is due to the fact that not only is Ruby a dynamic language, it is also dynamically typed. This means that all types are implicit. Since we assigned “1″ to the “count” variable it became a number, if we were to assign “abc” to it, then it would become a string. Like this:

count = 1
count = "abc"

This code in Ruby is completely valid. We can reassign this variable’s type as we see fit. Whether this is good practice or not is another story. Now, in C# everything is forced inside of classes, but in Ruby we don’t have to do this. So, Ruby needs global variables, so that files can access variables in other files. This is done like this:

$count = 1

The dollar sign designates that this is global. Ruby follows this idiom of using prefixes as access modifiers. Now, the next two types of variables we are going to talk about are in terms of classes, so I am going to show you real quick how to declare classes in Ruby. But first in C# we are going to declare a Person class:

public class Person
{
}

In Ruby this would look like this:

class Person

end

In C# we can declare two types of variables within a class, instance and static. As you know instance variables store a unique value within each class instance, while static variables declare a single values for all instances of a type. In C# these look like this:

public class Person
{
    protected int count;
    protected static int count2;
}

In Ruby these will look like this (One note is that Ruby static variables are usually referred to as “class variables”):

class Person
    @count
    @@count
end

One thing that you will also notice is that we have no types on the Ruby variables. This is because Ruby class and instance variables are, by design, not accessible from outside of the class. I used protected in the C# version because all ruby instance variables are accessible from descendant classes, there really is no private instance or class variables in Ruby. In order to get at these variables outside the class you have to specify methods to get or set these values. Now, this may sound like a pain and even give you Java flashbacks, but fear not, Ruby provides easy ways to do this. Just like in C# 3.0 we finally have our wonderful automatic properties:

public class Person
{
    public int Count { get; set; }
    public static int Count2 { get; set; }
}

Ruby provides a method that allows us to define “properties” called “attr_accessor” which only works for instance variables:

class Person
    attr_accessor :count
    @@count2 = 0

    def count2
        @@count2
    end

    def count2=(value)
        @@count2 = value
    end
end

So, you can see that we have defined methods to access our static variable, but we only need one line to declare our instance variable and methods to get and set it. One thing you may have noticed is that next to our “attr_accessor” the word “count” has a colon next to it. This is what in Ruby is called a symbol. It just allows us to assign pass a name around. In this case “attr_accessor” is simply a method that we are passing a symbol to. This method then creates an instance variable with the name of the symbol and get and set methods with the same name. The same could be done by passing a string in, only it would be much less efficient.

I think I am going to stop there for the night. You should know by now how to declare a variable, class, and variables inside classes. In the next post we will start to flesh out our class a bit more and do some operations on the data that we have defined.

Be Sociable, Share!

11 comments

  1. Justin, I hope you participate in open spaces at CodeStock and spark a conversation about learning Ruby with Iron Ruby.

    ++Alan

  2. This is a learning experience for me, I’m not sure how confident I feel with being an in-person teacher of this topic. I’m going to be plowing through a lot of it between now and Codestock, so we will see how it goes. :)

  3. FYI, I believe the equivalent of attr_accessor for class variations (public static / @@ variables), is cattr_accessor.

    hth!

  4. just to clarify, when you created your accessors for your @@count class (static) variable, you defined:
    def count2;end;
    def count2(value);end;
    the 2nd definition actually overwrote the first one, what you want is:
    def count2;end;
    def count2=(value);end;

    now, that said those are instance methods, meaning you’d need to create an instance of that class in order to call those methods. you could have defined them as class (static) methods like this:
    def self.count2;end;
    def Person.count2=(value);end;

    note that the use of self or the class name are interchangeable there, and that functionality is what cattr_accessor would have created for you anyway (as brought up by Andrew).

  5. @jacob Good catch, I have fixed this in the post. I will have to remember to make a mention in a future post about Ruby not supporting method overloading. And I just used instance method at that point because class methods were not discussed until the next post. Thanks!

  6. Hi Justin,

    Excellent series of tutorials! I am hoping to make my colleague .NET developers enthusiastic about (Iron)Ruby and I’m directing them to your site. Keep up the good work!

    Erik

  7. Hi Justin, Thanks a lot for interesting series on ironruby.

    I just had a small query. I am using ScintillNet in my application and I want to have script validation facility (which ScintillNet doesn’t provide). Can you suggest me a simple way to do this? Does ironruby provide this API? Can I use ironruby as Managed dll in my application directly?

    Thanks in advance,
    Ujjwal

  8. @Ujjwal Yep, the license for IronRuby is pretty liberal. You can ship your application with the IronRuby dll and run your scripts with it. I think this post might help: http://stackoverflow.com/questions/2293279/use-an-ironruby-wrapper-method-to-get-a-block-into-c

  9. You don’t need many reasons to dislike javascript – it just stinks.

    Anyway, thanks for the tutorial, it somewhat opened me to the Ruby world, I might try it.

    Thanks,
    Avi.

  10. Did you mean: One thing that you will also notice is that we have no [access modifiers] on the Ruby variables. ???

Leave a comment