Learning Ruby via IronRuby and C# Part 7

Writing

Click here to view the entire IronRuby via C# series

In the last part of this series we talked about hashes in Ruby and C# and we saw how they are very close in functionality. In this entry we are going to start looking at the parts of Ruby that do not easily translate directly into C#. In a few past posts you have seen some parts of Ruby that vary a bit from C#, but in most cases the languages are still very similar. You will now start to see the features that people brag about when they tout Ruby’s power over most statically typed languages.

The first feature that we are going to look at is called “duck typing”. It is really less of a feature and more an underlying principle of the language. “Duck typing” refers to the way in which objects are used polymorphically in Ruby. In C# an object’s class is its type and it represents the mechanism through which object can be manipulated. So, in C#, if you wanted to interact with a class then you need to know its type, one its base types or an interface supported by the type. So, lets define a tiny hierarchy here:

public abstract class Employee
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public abstract int VacationDays { get; }
}

public class Manager: Employee
{
    public override int VacationDays
    {
        get
        {
            return 25;
        }
    }
}

public class Developer: Employee
{
    public override int VacationDays
    {
        get
        {
            return 18;
        }
    }
}

In this you can see that we have a Employee class with Developer and Manager child classes. If we wanted a method to be able to operate on either a Manager or a Developer then we would create a method that used our Employee base class like this:

public void PrintEmployeeVacation(Employee employee)
{
    Console.WriteLine("Vacation Days: {0}", employee.VacationDays);
}

And now we could pass either a Manager or Employee in and we would print out their vacation. So, how would we do this in Ruby? Well, in Ruby this hierarchy would look like this:

class Employee
    attr_accessor :first_name
    attr_accessor :last_name
end

class Manager < Employee
    def vacation_days
        25
    end
end

class Developer < Employee
    def vacation_days
        18
    end
end

But if we created the same method then we would create it to look like this:

def PrintEmployeeVacation(employee)
    puts "#{employee.vacation_days}"
end

So, that looks very similar to the C# method, but there aren’t any types. So how does that work? If we aren’t specifying any types, how does Ruby know that it is valid to call “vacation_days” method on the object? This is where Ruby’s duck typing comes in. Since in Ruby a class is not its type, Ruby simply relies on whether or not a class has an implementation of a particular method. Which is why it is called “duck typing”, because “if it walks like a duck, and talks like a duck, then it must be a duck”!

And since Ruby doesn’t rely on anything other than the fact that a class supports a particular method, we see that there is nothing regarding the “vacation_days” method in the “Employee” class at all. Ruby has no concept of an abstract class or method. And guess what, that means that these classes don’t need to share a base class! In fact, Ruby has no concept of interfaces, and so you don’t need one of those either. So, we could define these classes like this:

class Manager
    attr_accessor :first_name
    attr_accessor :last_name    
    
    def vacation_days
        25
    end
end

class Developer    
    def vacation_days
        18
    end
end

Notice that there is no first name and last name in the Developer class. I took those out so you can see that they don’t share a base class and they don’t even have an identical implementation. Ruby just doesn’t care. It doesn’t matter to the “PrintEmployeeVacation” method because it only uses the “vacation_days” method. This means that any class which has a method called “vacation_days” which returns a value that can be used in the “puts” method will work in this method. This means that we could change the Developer class to this:

class Developer    
    def vacation_days
        "18"
    end
end

And it would still work. Since the string “18” is valid in the context of our method, then execution would occur as normal. How is that for flexibility?

But all of this flexibility also comes at a cost. In fact, most of you who are used to static languages may be sitting there with your mouth agape in horror. You are probably thinking “you can pass anything into that method, and if the ‘vacation_days” method isn’t supported then it will just blow up!”. What about if an object is passed in that has the method which doesn’t perform the same operation, or return a valid result, or takes parameters? Well, you will get a runtime error. Because of that you may be shaking your static head and saying, “but how would you ever control the behavior!?”

The answer is unit testing. In dynamic languages, just like in static languages, everything should be unit tested. Sure the programmer must to have better knowledge of what an object needs in order to be passed into a particular method, but the lack of compile time checking is one of the fundamentals of dynamic programming. It is not a weakness, it is a feature! If the thought of not having every parameter on every method checked for type makes you lose sleep, then dynamic languages may not be for you. The important thing is that you must use heavy testing in order to flush out these errors and keep your code quality high.

I hope you enjoyed this look at the power and flexibility of Ruby’s duck typing, in a future post we are going to delve a bit more deeply into Ruby’s type system by introducing you to modules in Ruby. Have fun!

Loved the article? Hated it? Didn’t even read it?

We’d love to hear from you.

Reach Out

Comments (7)

  1. I’m just jumping into this series in the middle of it. While I already understand this, I really appreciate how well you explained it. I’m definitely going to read this blog series from the beginning.

  2. Hi,

    Perhaps this link can help you to move faster with LINQ and IronRuby. This is a new blog appeared today on Asp.Net website.

    http://www.progtalk.com/ViewArticle.aspx?ArticleID=68

    I think, Asp.Net MVC (IronRuby) and LINQ would be the best way to go. There are two books currently announced. (1) Pragmatic publishers and (2) Wrox. Both have the same mission to convert the .Net developers to work with Ruby On Rails.

    Your approach is rather different and perhaps the best way, since it explains IronRuby, so that .Net developers can decide the best way to go with either (1) IronRuby on Rails… (2) Asp.Net MVC with IronRuby and Linq/Active Record or (3) Asp.Net( web forms ) with IronRuby and LINQ.

    Since frameworks are ruling the internet, i think… your focus should be more on MVC rather than plain Asp.Net.

    Just my 2 cents

  3. @Justin I would say that "Duck Typing" is a side effect of dynamic typing. In my original comment though, I was simply mentioning my preference for dynamic typing. As opposed to simulating "Duck Typing" via a hack in a statically typed language such as C#…

Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

More Insights

View All