Ruby Quick Reference

About

A personal ruby quick reference. I have quite a bit of experience with Perl, so I’ve taken some shortcuts; this isn’t completely a beginner’s guide, but for someone getting acclimated from Perl to Ruby, perhaps.

A large part of this reference is due to that of Zen Spider’s.

[1.8.6 Core] [1.8.6 Standard Library]

[print_link]

Index

table.ruby td, table.ruby th { border: 1px solid #ccc; padding: 3px; }
table.ruby tr.alt td, table.ruby tr.alt th { background-color: #ccc; }
table.ruby th { text-align: left; width: 125px; }
table.ruby pre { background-color: #fff; }

Running ri (aka Ruby’s perldoc)

ri Displays help
ri Class Toplevel docs for Class
ri Class.method Specific docs for method
Can be class or instance method
Can be operator overloading like [] or ==

Numbers

Decimal 123, 1_234, 1234.45, 1.2e-3
Radixes 0xffffff, 0b01011, 0377
Characters ?a, ?\C-a, ?\M-a, ?\M-\C-a
Convert (usually String) to_i, to_f

Strings

Quoting

Interpolation “#{expression} \n”
%Q("#{expression}" \n)
No interpolation 'no interpolation'
%q(no interpolation)
Command `shell command with interpolation`
%x(shell command with interpolation)

Here Documents

Interpolation <<end, <<"END"
Indented <<-END, <<-"END"
No interpolation <<'END', <<-'END'

String Methods

[String]


s1 + s2 / s1.append s2
s.trim/s.trim! # remove whitespace
s.split(pattern, [limit])
s.empty?
s % arg1 / s % [arg1, arg2] / s.sprintf(arg1...)
s * n # n copies of s
s.sub(pattern, replacement)/s.sub!(pattern, replacement)
s.gsub(pattern, replacement)/s.gsub!(pattern, replacement)

Note on sub and gsub: in replacement, you can use '\1', '\2', etc., to refer to subgroups in pattern. Make sure that the \n is unescaped, or else you’re probably inserting a control character.

Class/Constant/Variable Naming


$global_variable
@instance_variable, instant_method
@@class_variable, Class.class_method
[OtherClass::]CONSTANT
local_variable
Class, Module

Predefined

self Like Java’s this
true, false Boolean constants
nil Like Perl’s undef, Java’s null
STDIN, STDOUT, STDERR Standard I/O streams
ENV Hash of environment variables
ARGV Command-line arguments

Ranges

[Range]

Literals 1..10, 'a'..'z'
Part of range? (1..10) === 5 is true, (1..10) === 15 is false
Lines from /start/ to /end/
while gets
    print if /start/../end/
end
Iteration
(must support succ)
(start..end).each { |n| ... }
Custom Range Class Methods: def (rhs), def succ
def succ
range = CustomRange.new(lower)..CustomRange.new(upper)

Regular Expressions

Regular Expression Syntax

/normal regex/[xim] x: ignore unescaped whitespace
i: case-insensitive
m: multi-line
%r|alternate regex|[xim]
Regex.new(pattern, options)

Less Common Sequences in Regular Expressions

Non-greedy *?, +?
At least/but at most #{m,n}, #{m,n}?
Boundaries Word boundary: \b, Non-word boundary: \B
Comments (?#)
No backrefs ($1 etc) (?:)

Operators: Interesting

Note:

  • Operator overloading exists.
  • There is no ++ or --; use += and -=, and yes, you miss other things, but whatever
<< Append (arrays, strings, I/O)
=== Member of/contained in
.. vs … Inclusive vs. Exclusive
** Exponentiation

Defining a Class

class Class < Superclass ... end

# Singleton classes
class << single_object ... end

Defining a Module

module Module ... end

Attributes


(class|module) Name
    attr_reader :attribute1, :attribute2
    attr_writer :attribute3, :attribute4
    attr_accessor :attribute5, :attribute6

    def attribute7
        return @attribute7
        # can be called as name_instance.attribute7
    end
    def attribute7=(val)
        @attribute7 = val
        # can be called as name_instance.attribute7 = expr
    end
end

Methods

Calling Methods

method
obj.method
Class.method
Class::method

method(arg1, arg2)
method(arg1, key1 => val1, key2 => val3)
method(*[arg1, arg2]) becomes method(arg1, arg2)

Defining Methods

def method(args) ... end
def Class.method(args) ... end
def obj.method(args) ... end

def method(arg1, arg2 = default)
    ... arg1 available/required ...
    ... arg2 optional/default value ...
end

def method(arg1, params)
    ... arg1 available/required ...
    ... params collects all key => value pairs from call ...
end

def (rhs) ... end     # just about all operators including []
def []=(index, rhs) ... end 

Access Restriction

public :method
public
    def method1 ... end
    def method2 ... end

# Similarly for protected and private

Blocks (Full Closures)

def method(args)
    yield [block args]
end

method(args) do [|var|] ... end
method(args) { [|var|] ... }

Control Expressions

If/Unless

(if|unless) (bool-expr)
    body
elsif (bool-expr)
    body
else
    body          # else is optional, unlike perl
end

expr (if|unless) (bool-expr)

Case

case target-expr
when expr, /regex/, r1..r2
    body
else
    body
end

Loops

(while|until) (bool-expr)
    body
end

begin
    body
end (while|until) (bool-expr)

for name[, name] in expr
    body
end

expr.each do | name[, name] |
    body
end

expr (while|until) bool-expr

Breaks/Continue etc.

break, next The usuals
redo Redo without re-running condition
retry Redo with re-running condition

Exceptions

Exception Syntax

begin
    expr
rescue [exception_class] [=> var]
    expr
else
    expr
ensure
    expr           # Like Java's finally
end

raise [exception class], [message]   # class defaults to StandardError

Common Exception Classes

StandardError RangeError, IOError (EOFError), ThreadError, ArgumentError, IndexError, RuntimeError, TypeError, RegexpError, SystemCallError
SignalException
Interrupt
NoMemoryError

Arrays

Array Syntax


[ expr1, expr2, expr3, ]
a[index]
%w(foo bar baz) => [ 'foo', 'bar', 'baz', ]
%W(foo, #{2 * 2}, baz) => [ 'foo', '4', 'baz', ]

Array/Enumerable Methods

[Enumerable] [Array]


enum.collect { |e| block } == a.map { |e| block }
enum.include?(obj) == a.member?(obj)
enum.find_all { |e| block } == a.select { |e| block } # like Scheme's filter
enum.grep(pattern) { |e| block }
enum.inject(initial) { |acc, e| block } # like Scheme's reduce
enum.size


a1 + a2 / a.concat(a2)
a.delete(obj)
a.flatten/a.flatten!
a.map/a.map!
a.reject/a.reject!
a.reverse/a.reverse!
a.each { |e| block }
a.each_index { |index| block }
a.push expr / a << expr / a.pop # from the end
a.unshift expr / a.shift # from the beginning
a.slice(index)/a.slice(start, length)/a.slice(range)
a[index]/a[start, length]/a[range]
a.sort { |a, b| compare a and b }/a.sort!
a.join('delim')

Hashes/Maps

Hash/Map Syntax

{ expr1 => expr2, expr3 => expr4, }
hash[key] = value
hash[key]

Hash/Map Methods

[Hash]


h.keys
h.values
h.delete(key)
h.has_key?(key)
h.has_value?(value)
h.each { |key,value| block }
a.each_key { |key| block }
a.each_value { |value| block }

Files

File I/O

[IO] [File]


File.new(path, [w|a])
File.open(path, [r|w|a]) { |file| ... }
File.open(path, [r]).each { |line| ... }
IO.foreach(path, [line separation]) { |line| ... }
IO.readlines(path) => [line1, line2, ...]
(io_object|STDIN).each { |line| ... }
(io_object|STDOUT|STDERR).puts(object)

File Utilities

[File] [FileUtils]


File.basename(path)
File.compare(from, to, verbose = false)
File.exists?(path)
File.directory?(path)
File.join(path1, path2, path3)
FileUtils(::Verbose).cp(src(s), dest)
FileUtils(::Verbose).cp_r(src(s), dest)
FileUtils(::Verbose).touch(path)
FileUtils(::Verbose).unlink(path)

Directories

[Dir] [File] [FileUtils]


FileUtils.mkdir_p(path)
Dir.pwd
Dir.chdir
Dir.each
Dir.glob # * - all files; ** - recurse directories; **/* - everything

URI/URL

[uri] [OpenURI]

require 'open-uri'
 open("http://www.ruby-lang.org/",
          "User-Agent" => "Ruby-URI") do |f|
     f.each_line {|line| block }
 end

Test::Unit

[Test::Unit]

require 'test/unit'

class MyTestClass < Test::Unit::TestCase
    def setup ... end
    def teardown ... end
    def test_method
        # message builds upon the built-in message.
        # you don't need to re-add the built-ins
        assert(condition, [message])
        assert_equal(expect, actual, [message])
        assert_nil(expr, [message])
        flunk
    end
end

REXML

[REXML] [Tutorial] [w3c Xpath] [XSLT/Xpath reference]

require "rexml/document"
file = File.new( "mydoc.xml" )
doc = REXML::Document.new file

# text

doc.elements[1]     # indexing begins at 1

doc.elements['root/to/singleton'].(name|attributes|text)
doc.elements['root/to/plural[1]']

doc.elements.each('root/to/plural') { |element| block }

e_child = doc.elements['root/to/single']
e_child.elements.each { |element| block }

(element|attribute).prefix          # namespace

RDoc

[rdoc]

=begin rdoc
Documentation for the file.
=end

# Paragraph of documentation that continues unto
# the next line.
#    This is verbatim code
# http://links/are/linkified
# Module::Class are automatically linked
# method_name or #method are automatically linked
#
# 1. Numbered list
# 2. Another in the list (could have been 1. too)
# ** nested unordered list
#
# [label]    definition
#
# label::   definition in a table, all lines up
#
# = Level one heading
# == Level two heading
# _italic_ *bold* +typewriter+
#
#--
# Stop comment processing by Rdoc

#++
# Start processing by Rdoc again
#

Option Parsing

[optparse]

require 'optparse'

options = {}
opts = OptionParser.new do |opts|
    opts.banner = "Usage: name.rb  [options]"

    # Boolean option
    opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
        ... v is true or false ...
    end

    # Mandatory argument
    opts.on("-r", "--require ARGNAME", "message") do |v|
        ...
    end

    # Optional argument
    opts.on("-i", "--inplace [EXTENSION]", "message") do |v|
        ... v can be nil ...
    end
end
opts.parse ARGV

Open Struct

[ostruct]

require 'ostruct'
struct = OpenStruct.new
struct.a = 1
struct.b = 'a string'

puts struct.a
puts struct.b

Temporary Files

[tempfile]

require 'tempfile'

Dir.tmpdir            # System's temporary directory
tmpfile = TempFile.new('basename')
tmpfile.puts "a line"
tmpfile.write"a string"
tmpfile.close

tmpfile.unlink

Time and Date

[date] [time] [strftime format]

require 'time'

t = Time.new
t.strftime           # has a verbose default format (%F)
t.strftime('%Y-%m-%d %H:%M:%S')
t.strftime('%I::%M %p')

Time.parse(date_string)    # uses heuristics

[print_link]