There is an interactive Ruby shell where you can play with stuff:
shell$ ibr
Ruby has a class documentation utility.
shell$ ri Float
shell$ ri String#chop
Since linebreaks indicate the end of an expression (not semicolons), multiline expressions should have a line continuation chatacter (a backslash).
foo = "All one long line that can be joined together by " \
+ "a backslash"
Ruby comments begin with a pound (#). Anything on a line after a # is ignored. Longer comments are possible with =begin and =end:
# This is a single-line comment.
foo = "bar" # A comment after a statement
=begin
************************************************
This is a much longer multi-line comment that is
delineated by the '=begin' and '=end' directives (?)
before and after this comment. (The splats are purely
decorative.)
************************************************
=end
Simple math:
1 + 3 # => 4
2 * 2 # => 4
3 ** 2 # => 9 (exponential)
5 % 2 # => 1 (remainer)
Large numbers can be writting with underscore speparator (just for visual comfort):
1_999_999 == 1999999
String concatenation looks like:
"foo" + "bar" # => "foobar"
You can do stuff with strings:
"hello".capitalize # => "Hello"
"hello".reverse # => "olleh"
"hello".next # => "hellp"
"hello".upcase # => "HELLO"
"HELLO".downcase # => "hello"
"HellO".swapcase # => "hELLo"
"hello".length # => 5
"hello".empty? # => false
"hello".include? "hell" # => true
"hello".chop # => "hell"
"hello".reverse.reverse # => "hello"
Type coersion (converting between classes) can be accomplished like this:
3.to_s # => "3" (integer to string)
"3".to_i # => 3 (string to integer)
3.14.to_i # => 3 (float to integer)
3.to_f # => 3.0 (integer to float)
Variables must be lowercase.
foo = "Bar"
foo += "Baz" # => "BarBaz"
Constant variable names can (and should) be all uppercase.
PI = 3.14159265
Global variables begin with at dollar sign:
$global_variable = "foo"
Symbols start with a colon. I don't understand symbols yet.
:a_symbol
Using symbols in an array of hashes:
widgets = [
{:color => 'red', :weight => 3},
{:color => 'blue', :weight => 22},
{:color => 'green', :weight => 11},
]
widgets.sort_by { |w| w[:color]}.each do |w|
puts "The weight is #{w[:weight]} pounds."
end
Arrays:
foo = ["foo", "bar", "baz", "bat"]
foo[0] # => "foo"
Arrays can contain mixed classes of objects:
bar = ["fred", 3, foo]
Some array methods:
foo.length # => 4
foo.sort
foo.reverse
foo.delete(3) # Deletes all array element == 3.
foo + ["nerf"] # => ["foo", "bar", "baz", "bat", "nerf"]
foo - ["bar"] # => ["foo", "baz", "bat", "nerf"]
There's a list of arrary methods.
Hashes:
zoo = {
"tiger" => "Mamal",
"turtle" => "Reptile",
"beetle" => "Insect"
}
Add one hash element:
zoo["whale"] = "Mamal"
Iterate through hases like:
zoo.each do |key, value|
puts key + " : " + value
end
Hash methods:
zoo.each_pair # Same as zoo.each
zoo.each_key
zoo.each_value
Class names are capitalized. Literals are not actually literals, they're classes: Integer, Float, String. You can find out if an object belongs to a class:
12.is_a?(Integer) # => true
12.class # => Integer
Do loop:
# Prints "foo" three times
i = 3
i.times do # i can be a literal, like '3.times do'
puts "foo"
end
While loop:
i = 0
while i < 10
puts "Count: " + i.to_s
i += 1
end
Iterators:
colors = ["red", "blue", "green", "indigo"]
colors.each do |color|
puts "The color is: " + color
end
also:
colors.length.times do |i|
puts "Color: " colors[i]
end
also:
colors.sort.each do |color|
puts "Color: " color
end
Iterate through hases like:
zoo.each do |key, value|
puts key + " : " + value
end
if foo == "bar"
x = 1
elsif foo == "baz"
x = 2
else
x = 0
end
Function with no arguments:
def doSomething
puts "Something"
end
doSomething # => "Something"
Function with an argument:
def doSomethingSpecific(thing)
puts thing
end
doSomethingSpecific("Pizza") # => "Pizza"
Yield:
def marines
yield("missle turret")
yield("bunker")
end
marines do |m|
puts "Unit: " + m
end
Also:
def players
yield("Jay", "LaBelle")
yield("Jake", "Kallie")
end
players do |first, last|
puts first + " " + last
end
Define classes like:
class Animal
attr_reader :species # Make @species readable from outside object
attr_writer :species # Make @species writable outside object
# attr_accessor makes the object value both readable and writable
def initialize(species)
@species = species # The @ denotes a object variable.
end
end
Instantiate an object from a class:
myAnimal = Animal.new("tiger")
Play with the object:
myAnimal.species # => "tiger"
myAnimal.species = "rabbit"
Another class:
class Vehicle
attr_accessor :wheels :topSpeed :passengerCapacity
def initialize
@wheels = @topSpeed = @passengerCapacity = ""
end
define to_s
"Vehicle with " + @wheels + " wheels " \
+ "and a top speed of " + @topSpeed \
+ " and a " + @passengerCapacity + " passenger capacity.\n"
end
end
Custom object iterators:
class Garage
def each
@vehicles.each {|v| yield v}
end
def eachTopSpeed
@vehicles.each {|v| yield v.toSpeed}
end
end
Public and private object methods:
class SomeClass
def method1 # default to public
...
end
private # subsequent methods are private.
def method2 # private method
...
end
def method3 # private method
...
end
public # Set back to public.
def method4 # public method
...
end
end
Inheritance:
class Motorcycle < Vehicle
def initialize(wheels, topSpeed, passengerCapacity, sidecar)
super(wheels, topSpeed, passengerCapacity)
@sidecar = sidecar
end
def to_s
super + "Sidecar: " + @sidecar
end
end
begin
statements which may raise exceptions.
rescue [exception class names]
statements when an exception occurred.
rescue [exception class names]
statements when an exception occurred.
ensure
statements that will always run
end
The last exception is stored in the $! variable (and its type can be determined using $!.type).
You can just use require to include one Ruby file in another. If the other file is a module, though, it provide a protected namespace.
module Foo
BAR = 3
def Foo.narf
# stuff...
end
end
Module used like:
require "Foo"
x = Foo::narf
Note that modules also provide mixin/superclass/multiple-inheritance functionality.
© Paul Gorman.