Install Ruby using the RubyInstaller. Other versions of Ruby can be found at the RubyInstaller website.
Chances are you have Ruby installed already. Open /Applications/Utilities/Terminal.app and type
ruby --version
You should get an output like:
ruby 2.0.0p481 (2014-05-08 revision 45883) [universal.x86_64-darwin14]
You may have Ruby preinstalled, depending on your distro. Open a terminal and type
ruby --version
If you get an error, install Ruby using your distro's package manager.
irb
is Ruby's REPL (read-eval-print-loop). When run from the command line, you will be presented with a prompt like this:
irb(main):001:0>
Here, you can type any Ruby code, have it evaluated, and the results printed out as output. It is very handy for testing bits of Ruby code.
Ruby is a dynamically typed language, meaning that variables do not need to specify types, since Ruby is very smart and can figure it out on its own. The following code snippet illustrates this:
x = 5
puts x # puts() is equivalent to println()
x = "Hello, world!"
print x # print() is equivalent to print()
First, x
is an integer, then it is set to a string! In Java, this would be illegal, but Ruby is perfectly ok with it.
Ruby functions are many, many times more powerful than Java functions. Before we see how, let's look at a simple function:
def say_hello(name)
puts "Hello, #{name}!"
end
say_hello("Mr. Davis")
say_hello "Sterling Archer"
This example illustrates a few important things about functions, and the Ruby language in general. Let's look at this function next to its Java equivalent:
public void sayHello(String name)
{
System.out.println("Hello, " + name + "!");
}
def say_hello(name)
puts "Hello, #{name}!"
end
Functions are defined as def func_name(args) ... end
end
#{}
Arguments can be surrounded with parentheses, or not
Let's look at a simple class definition for a rational number, or fraction:
class Fraction
def initialize(numer, denom)
@numer = numer
@denom = denom
end
def numer
@numer
end
def denom
@denom
end
def numer=(numer)
@numer = numer
end
def denom=(denom)
@denom = denom
end
def to_s
"#{@numer}/#{@denom}"
end
end
two_thirds = Fraction.new(2, 3)
puts two_thirds
two_thirds.denom = 4
puts "Two thirds is not #{two_thirds}!"
We've defined a simple class with two instance variables, numer
and denom
. There are setters and getters (using Ruby's awesome syntactic sugar), and even a method to convert the Fraction to a string!
Things to note:
initialize()
, but classes are instantiated with new()
Defining a method to_s
will allow conversion to a string
to_i
to convert to an integerto_a
to convert to an arrayHowever...this is not how we actually write classes in Ruby. That's a lot of typing, and we as Ruby programmers hate unnecessary typing. So, let's refactor this class into good, Ruby style:
class Fraction
attr_accessor :numer, :denom
def initialize(numer, denom)
@numer = numer
@denom = denom
end
def to_s
"#{@numer}/#{@denom}"
end
end
Much better! The keyphrase attr_accessor
will automagically create getters and setters for each property (written as Ruby symbols
when prepended with :
). Using attr_writer
or attr_reader
will create only setters or getters, respectively. You can use any or all of these at once, for different properties.
Ruby arrays are more akin to linked lists in Java, in that they are not bound to a specific size, or even stored type! Let's look at a quick example of Ruby arrays:
arr1 = []
arr2 = Array.new
arr1 << 1
arr1 << "Hello!"
arr2 << "I shouldn't print!"
arr2.pop
arr2 << 42
arr3 = Array.new(3, 5)
puts arr1 # => [1, "Hello!"]
puts arr2[0] # => 42
puts arr3 # => [5, 5, 5]
x = 5
if x.eql? 42 then
puts "So long, and thanks for all the fish!"
elsif x.eql? 5 then
puts "X is 5!"
else
puts "This is an else clause!"
end
There is also an "opposite if" expression in Ruby, called unless
, which can be very helpful
x = 5
unless x.eql? 42 then
puts "X is not the answer to life, the universe, and everything"
end
i = 0
while i < 10 do
puts i
i += 1
end
i = 0
until i.eql? 10 do
puts i
i += 1
end
arr = Array.new(5) do |index|
index * 2
end # Create an array of five elements, with each value being (index * 2)
arr.each do |elem|
puts elem
end
arr.each_index do |index|
puts "Element at index #{index} is #{arr[index]}"
end
puts "Welcome to my program!"
print "Enter a number: "
num = gets.chomp!.to_i
# Without the call to chomp!(), we would have the newline character as well
# to_i() will convert the string from gets() to an integer
puts "You entered #{num}!"