A Perl Monger’s take on Ruby: Part II

In part one I started talking about a few differences between Ruby and Perl. Let’s continue with a few other topics I think are key to understanding both of these languages.

Object-Oriented programming

Most everyone these days does it, though some will argue what “it” really is. There are clear benefits, regardless of the specifics of your definition, and the vast majority of modern languages support writing Object Oriented code in one form or another. Ruby, as with a few other languages (notably, Python), takes OO to the extreme — everything is an object. Even the most simple code contains objects. Care to guess how many objects this line contains?

['a', '2', 'Z'].join(',')

How does 5 sound: one list and four string objects. Another classic example is calling methods on things that would not be objects in other languages, such as in this script:

2.times do |x|
  puts "#{x} - Hello"
end

# prints
# 0 - Hello
# 1 - Hello

Ruby’s object model is well-defined and imposes certain constraints. It supports single inheritence, for example, along with a mechanism it calls the mixin. I find it useful to think of a mixin as a set of behaviors (verbs — what does it do?), and the standard inheritance as a type or thing (noun — what is it?). You can have multiple mixins with any given class; you can even add them at run-time if you’re looking for some metaprogramming fun (more on that later). But you can only have one direct parent class.

I would argue that Perl’s object model imposes fewer constraints. Want multiple inheritance? No problem, just be sure you know how it will dispatch your method calls in case of conflict. Most of what it does is relativly simplistic and can be manipulated, though the code needed to do that is anything but pretty. Combine that with CPAN and you have your choice of object models (Moose, Class::C3, Class::InsideOut, etc.).

Metaprogramming

Of course you can’t mention OO programming in a language like Perl or Ruby and not mention metaprogramming. I’m not going to go into much depth here in an effort to avoid arguments and simply say that if you can do it in one of Perl or Ruby you can almost certainly do it in the other. Both can do things like redefine classes and/or objects on-the-fly, or intercept messages when a called method wasn’t found. Very powerful stuff. Ruby’s way is much easier to understand, though.

Modules/Classes/Packages

In Ruby there are two different constructs for organizing code: Classes and Modules. A class is the basis for OO programming; it’s a collection of properties and methods that describe a reusable functional unit. A module is a collection of related items: classes, properties, and/or methods. Modules are also the basis for creating mixins.

Contrast that with Perl’s one method, the package, and you have some potential confusion for those such as myself who are more accustomed to Perl’s method. Also throw in a few other restrictions, such as not being able to have a module and class with the same name, or that people don’t seem to nest modules, and I find I’m even less sure how I would organize my huge Perl library at work if it were Ruby. So if anyone has a suggestion, please share in the comments!

Methods vs. Subroutines

Once again Perl and Ruby appear similar on the surface, but there are two differences between Ruby’s methods and Perl’s subroutines I think are important.

First is that Ruby differentiates between class and instance methods as a core language feature. In Perl it is up to the developer to determine whether the subroutine was called as a class or instance method. Either way works for me.

Second is the way parameters to methods are handled. In Perl it is easy to have named parameters to methods, which is something I find leads to very flexible methods and method calls that are easy to understand. Working with Ruby I find myself forgetting the order in which the parameters were supposed to be given. There are ways to do similar things in Ruby but they don’t feel quite the same to me.

Ruby

def blah(args)
  puts args[:name]
end

blah({:name => 'the_name'})

Perl

sub blah {
    my %args = @_;
    print $args{name}, "n";
}

blah(name => 'the_name');

Exception handling

Perl’s exception handing is both a blessing and a curse. I don’t have to go through the rigamarole Java developers do (I’ve always thought declaring what exceptions could be thrown was a bit of a pain…), but there is also no concrete way to handle different types of exceptions unless you like testing the text returned from eval statements. Ruby, on the other hand, has a more java-like idiom without being quite so cumbersome. It has a complete exception handling structure including catching specific types of exceptions (rescue ErrorType) and ensuring a block of code gets executed in all circumstances (ensure).

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*