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
- Numbers
- Strings
- Quoting
- Here Documents
- Methods
- Convert to string:
obj.to_s
- Arrays
- Hashes/Maps
- Files
- uri / OpenUri
- Test::Unit
- REXML
- RDoc
- Option Parsing
- Open Struct
- Temporary Files
- Time and Date
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
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
| Literals | 1..10, 'a'..'z' |
|---|---|
| Part of range? | (1..10) === 5 is true, (1..10) === 15 is false |
| Lines from /start/ to /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
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
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
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.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
FileUtils.mkdir_p(path)
Dir.pwd
Dir.chdir
Dir.each
Dir.glob # * - all files; ** - recurse directories; **/* - everything
URI/URL
require 'open-uri'
open("http://www.ruby-lang.org/",
"User-Agent" => "Ruby-URI") do |f|
f.each_line {|line| block }
end
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
=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
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
require 'ostruct'
struct = OpenStruct.new
struct.a = 1
struct.b = 'a string'
puts struct.a
puts struct.b
Temporary Files
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]