Five Ruby Hello World greetings

The Hello World program is the most common first example of how to write programs in a new language, even when they don't say Hello World. Five different ways to say hello in Ruby offer a gentle introduction to the language.

Examples of how to write many simple programs that are of little practical use litter the Internet for anyone to find. Among the most common are:

a Fibonacci number calculator, because it is the canonical example for recursion.

a FizzBuzz solver, because it has become a canonical example of a simple job interview coding question.

a Hello World greeter, because it is the canonical example used to introduce a language.

While teaching someone a new programming language in any depth requires a lot of discussion of syntactic forms, semantic design, and "best practices," it usually does not make much sense to the student until he or she gets to see a few examples of source code. This is where the Hello World program comes in: It is usually the first code example presented to a complete beginner, to give the simplest possible example of how the language looks in actual use. More complex examples follow, often involving the addition of more complexity and functionality to the Hello World program until it is nearly unrecognizable as a descendant of that first program.

It is easy to dismiss the Hello World as a meaningless toy, but it serves an important purpose that more experienced developers may forget later in their careers: With a little creativity, such programs can even demonstrate the flexibility and unique qualities of the language to some small extent. For those of you who have never used Ruby, the following Hello World examples in the Ruby programming language may serve that purpose. Each example includes a standard shebang line that tells the OS where to find the Ruby interpreter on a Unix system.

1. The simple example

#!/usr/bin/env ruby

puts 'Hello, world!'

There is not much to this. It consists of a grand total of two tokens — the puts method and a string datum. Similar languages such as Perl and Python would use print instead. For instance, the same program in Perl might look like this:

#!/usr/bin/env perl

print "Hello, world!\n";

The double quotes and \n newline character are necessary here if you want a newline at the end of the program's output. Ruby has a print method that behaves the same way, but it also offers puts, which conveniently adds the newline character at the end of its output without having to be asked.

2. The input example

#!/usr/bin/env ruby

puts "Hello, #{ARGV[0]}!"

In this case, we are using double quotes for an interpolated string — that is, a string that is actually parsed for executable code and special characters that should not be taken literally by the Ruby interpreter. Code that you want evaluated before passing the double-quoted string to the puts method can be wrapped in #{ }. In this case, we want the ARGV array — where Ruby stores input from the command line — to give us its first element. Because Ruby starts counting array elements at zero, that means we need ARGV[0] evaluated.

If you name this program hello.rb and feed it world as a command line argument when you execute the program, the output will say Hello, world!:

> ./hello.rb world

Hello, world!

3. The array example

#!/usr/bin/env ruby

greeting = ['Hello', ARGV[0]]

puts greeting.join(', ') + '!'

Here, we first create a two-element array and give its second element the value of the first element of the ARGV array so that the user, as in the previous example, can specify the target of a greeting. Next, the join method is passed to the greeting array object, telling it to join its elements together with a comma followed by a single space between any two elements. Finally, it adds (concatenates, in this context) an exclamation point to the end of the string, before the puts method finally attaches a newline to the end and sends the whole string to standard output.

If we run this program on a Monday, with a long, frustrating workweek ahead of us, we might be feeling less charitable than in the previous examples, and call the world something a bit less friendly:

> ./hello.rb 'cruel world'

Hello, cruel world!

This version uses a little unnecessary complexity to achieve the exact same effects as the previous example, but that complexity does demonstrate for us a couple of things:

It displays some of the convenient text-processing capabilities of Ruby, including two ways to connect separate strings together into a larger string.

It begins to show the object-oriented design of Ruby.

People who know object oriented programming from working with other languages might look at a lot of the code from before this example and wonder why everything in Ruby looks procedural, when it has a reputation as an object-oriented language. Prior to this, one could not tell just by looking at it that objects and methods infested the Ruby source code for a Hello World program. It turns out that puts is a method of the Kernel class, and strings are object instances of the String class. Array objects come with a join method, and while it looks like a procedural infix operator, + is actually being used here as a String object's method. In fact, the last line of this version of the Hello World program can be written like this, more explicitly revealing these methods for what they are:

Kernel.puts( greeting.join(', ').+('!') )

Thank goodness for syntactic sugar; the version that does not use as many parentheses, does not explicitly name the Kernel class, and does not use as much dot-notation for methods was a bit easier on the eyes.

4. The custom method example

#!/usr/bin/env ruby

def greet(target)

return "Hello, #{target}!"

end

puts greet(ARGV[0])

With another bit of unnecessary complexity, this time we have separated the string-building process from the output process by constructing a method called greet. By creating the greet method without explicitly including it in any class definition, we have added it to the Kernel class. As with puts, we do not need to specify the class to which the method belongs. In fact, because greet is a private method of Kernel, it cannot be called like this:

Kernel.puts Kernel.greet(ARGV[0])

Actually, it can in irb (the interactive Ruby interpreter), but with standard executable files, this will not work.

Once again, even when we create a method, we are doing something that could easily be mistaken for using a programming paradigm other than object-oriented programming. In this case, it looks like functional programming, where we have defined a "function" that takes exactly one input, produces exactly one output, and has no side effects. That "function" is then used to provide its output as input for another "function", the puts method. It is only because we know that both of these supposed functions are in fact methods of the Kernel class that we know this is a purely object-oriented exercise.

If you want to develop code in a functional style, you may simply ignore what is going on behind the scenes and write your code in a manner calculated to give the impression it is purely functional, and not object oriented at all.

5. The custom class example

#!/usr/bin/env ruby

class Greeter

def initialize(greeting)

@greeting = greeting

end

def greet(subject)

puts "#{@greeting}, #{subject}!"

end

end

hail = Greeter.new('Well met')

hail.greet(ARGV[0])

farewell = Greeter.new('Goodbye')

farewell.greet(ARGV[1])

Finally, we are getting into the thick of object-oriented programming a little bit. A Greeter class is defined, and its initialize method (which automatically aliases to new) takes an argument for the type of greeting you want an instance of that class to use. Another method, greet, takes a single argument as well — the subject, or target, of your greeting.

Two separate objects of this class are instantiated with the new method, each of them being assigned to a separate label at the time they are created: hail and farewell. Each object is then sent the greet message with the first and second elements of the ARGV array, respectively, so that the person running the program from the command line can specify who will receive each greeting.

Let us assume that the person running the program gets up happy and optimistic on a Friday morning, looking forward to a quick and painless day of work, followed by a long weekend (Monday will be a holiday for this user). As such, when the user says hello, it is with a smile and a friendly outlook for the world. By the end of the day, however, this user's entire department has been laid off. To top it off, our hapless user has just bought a new, expensive house that he simply cannot afford without that job, and the economy is in the toilet. As such, he has a very emo moment when it comes time to say goodnight.

Given such a turnaround in his day, the program is run thus, complete with a teenage angst filled spelling error:

> ./hello.rb 'fine world' 'crule world'

Well met, fine world!

Goodbye, crule world!

If you become an expert Rubyist, you will hopefully never have the problem of being laid off so suddenly. I also hope that this quick introduction to Ruby gives you an idea of the language's clarity and flexibility.