This is the first part of what I hope will be a pretty useful set of tutorials for those moving from the world of Perl in to Ruby. For the overview of topic I hope to cover in this series you can go back and look at the “Overview” page. In this first part I want first to talk about how Perl and Ruby are similar and then go over some of the most visible differences.

Perl and Ruby really are BFFs

Way back in the 1990′s, the creator of Ruby (Yukihiro “Matz” Matsumoto) was a fan of Perl and so when he created the syntax for Ruby he borrowed a lot from Perl. Things like operators, conditionals, binary syntax and regular expressions are all existing in Ruby almost unchanged from how they exist in Perl 5.

The “unless” conditional, arguably one of the greatest things Perl ever popularized, is alive and well inside Ruby. While there are a lot of people who would prefer people to keep using !(condition), Ruby has unless ingrained as part of it’s culture and there is no reason you should not use in the same way you used it before.

Back-referenced conditionals, also know as putting the “if” after a statement of code, lives on in the same vein as unless. As in Perl, as well, you usually only ever see it with one-liners. So a Perl statement like:

print "foo!n" if $bar == "baz"; expressed almost identically in Ruby as:

puts "foo!" if bar == "baz"

Logic with && and || are used in conditionals throughout Ruby. There are also some places where the logical keywords “and” and “or” that, and while those may be pronounced the same way, function subtly differently. One difference, though, is with chaining executions using && or ||. Take, for example, some pretty common Perl code like:

my $arg = $ARGV[0] || die "please pass an arg!"

..although that may be technically possible with Ruby it is almost never seen in any production code.

Regular expressions are even more like first-class citizens than they where in Perl 5. We’ll cover more about what I mean by that then I get on the part about the Ruby object model, but right now suffice it to say that if you wrote lots of regexen like:

unless ($name =~ /Joe/i) {…

..then you’re going to be able to use that just the same way in Ruby with the same =~ operator. (and !~ works here too!)

You can still get command line arguments using ARGV, though there are a number of better options available if you’re going to do anything complicated. It’s still a zero-indexed array, too, same as you expect.

We’re still in script-land, so executables still start with a shebang, but it’s different than the universal standard shebang from the Perl universe. Whereas the expected shebang header from a Perl5 executable should be

#!/usr/bin/perl -w
use strict;

..most Ruby executable scripts will begin with

#!/usr/bin/env ruby

..where “env” is a common unix program to find the program with that name in the current path and execute it. There is only one type of syntax checking in Ruby so use strict or -w are superfluous.

Where they start to get really different

Semicolons are only Semi-necessary

The biggest difference you undoubtably notice is a general lack of semicolons. In fact, Ruby has no problem with semicolons, per se, but we just never use them in most cases. The reason is that it in breaking from it’s C-decendant it uses carriage-returns or newlines to denote the end of a statement of code.

You could put a semicolon at the end of each statement and the interpreter would not balk at that, but there is no need. Modern-day parsers can properly check multi-line statements without having to be given the hint of a semicolon.

There is one place where they are used still, though, and that is for putting several statements on one line. In that case it would change a block of Ruby code like:

puts "foo"
puts "bar"
puts "baz"

..would be changed to:

puts "foo"; puts "bar"; puts "baz"

.. and would execute the same result. Note that there is still no semicolon at the end of the last statement.

Parenthesis are really, like, not that popular

Following that whole ‘less is more’ mantra, you’ll also note that parenthesis are really not utilized like they would be in other places. This is another case of “you can if you want to but you don’t have to.”

For example, a regular evaluation in Perl:

if ($foo == $bar) { …

..would be expressed in a Ruby-esqu way as:

if foo == bar

Even though most of the time parenthesis are to used in evaluations. In this case they are used as a form if hinting to give to the parser — the Ruby parser is smart, very smart, but it’s not mind reader. If you have statement where the conditionals are dependent on one-another or need to be grouped then that is a place where you would need to use parenthesis:

if foo == bar && (baz == qux && quux == quuux)


if ((foo == bar) && ((baz == qux) && (quux == quuux)))

..are equivalent, but

if foo == bar && baz == qux && quux == quuux

..would NOT be equivalent in that the last two comparisons would not be seen as a linked as they are in the first two examples.

Tune in next week when:

  • I Make fun of Perl’s “unique” OO design.
  • Give a brief overview of OO, objects and methods under Ruby.
  • Talk about Symbols in Ruby which actually has more to to with OO than you may think.