General
Everything in Ruby is an object.
nil
is the null in Ruby.
Use require
to include other files in workspace.
irb
is the interactive ruby shell.
Comment
#
forms a single-line comment.
=begin
...
=end
is multiline comment, but no one uses them.
Function not found
If a function (or a method) is not found, Ruby calls the method_missing
method with the function name as id
and parameters as *arguments
. By default method_missing
raises a NameError exception.
Operations
**
for power.
Arithmetic is actually method on an object: 1+3
is actually 1.+(3)
.
Boolean
- Equality:
==
- Inequality:
!=
- Negation:
!
- And:
&&
- Or:
||
and
and or
keywords are like &&
and ||
in bash. They are only used as flow-control and never use them in boolean operation:
do_something() and do_something_else()
call the latter only the former succeeds.do_something() or do_something_else()
call the latter only the former fails.
In Ruby, only nil
and false
are falsey, 0 is evaluated to true
.
Data Structure
Assignment returns right-hand-side value, so assignments can be chained:
x = y = 10
Variable names uses snake_case (lower-case words chained with underscore), just like in C++ and Python.
Strings
Prefer single quoted strings for string literals, and use double quoted strings for additional inner calculations such as substitution: #{val}
inside another string invokes substitution of val
into the place.
+
concatenate strings, but not with numbers. Call to_s
method to convert number to strings.
puts
is Ruby’s printing method. It returns nil
.
Symbols
:pending
is a symbol. It is immutable, reusable constants represented by an interger value. It favors over strings for comparison.
Symbol is about who it is, not what it is. All references to a symbol shares the same object ID (hash key), but two strings with same content may not.
Arrays
Comma-separated values enclosed in square brackets. Values in an array can have different types.
Array index is zero-based, and accessor []
is also a method.
array[-1]
points to the last element.array[2, 3]
returns 3 elements from index 2 in a new array.array[1..3]
returns 3 elemens from index 1 to 3 in a new array.array << val
appendsval
to the end ofarray
.array.include?(1)
checks if 1 is inarray
.
Hash
Hash is Ruby’s primary dictionary with key/value pairs.
hash = { 'color' => 'green', 'number' => 5 }
new_hash = { defcon: 3, action: true }
Second form uses symbols as keys, and supported from Ruby 1.9.
- Look up by key:
hash['color']
. If the key doesn’t exist, returnsnil
. - Key set:
hash.keys
, value set:hash.values
. - Check existence:
hash.has_key?('color')
,hash.has_value?(5)
.
Conditions
if
if true
'if statement'
elsif false
'else if, optional'
else
'else, optional'
end
Do not use parentheses around the condition of if.
Ternary if
?:
exists in Ruby. However, only very simple conditional are recommended to use this form.
Unless
unless
is the opposite of if
. If the value is false then the expression is executed. Don’t use unless
with else
, use if
instead.
Modifier if and unless
You can use if
and unless
and modifiers:
<expr> if <condition>
Then <expr>
is executed only when <condition>
evaluated to true.
case
case grade
when 'A'
puts 'Way to go kiddo'
when 'B'
puts 'Better luck next time'
when 'C'
puts 'You can do better'
when 'D'
puts 'Scraping through'
when 'F'
puts 'You failed!'
else
puts 'Alternative grading system, eh?'
end
Cases can also use ranges:
case grade
when 90..100
puts 'Hooray!'
when 80...90
puts 'OK job'
else
puts 'You failed!'
end
Loops
for loops
for counter in 1..5
puts "#{counter}"
end
But no one uses for loops. Instead passes a block to each
method. A block is like lambdas, anonymous functions.
(1..5).each do |counter|
puts "#{counter}"
end
Or: (1..5).each { |counter| puts "#{counter}" }
.
Arrays and hashes can be iterated using each
.
while loops
counter = 1
while counter <= 5
puts "iteration #{counter}"
counter += 1
end
After the while condition, there is an optional do
, but it is omitted.
until loop
until loop executes while the condition is false.
Modifier while and until
Like if
and unless
, while
and until
can be used as modifiers.
Infinite loop
loop do
# break somewhere
end
creates an infinite loop. It’s generally the same as while true
.
Loop controller
break
: leave the loop block early.next
: skip the rest of the current iteration.redo
: redo the current iteration.
Exception handling
begin
# code here that might raise an exception
raise NoMemoryError, 'You ran out of memory.'
rescue NoMemoryError => exception_variable
puts 'NoMemoryError was raised', exception_variable
rescue RuntimeError => other_exception_variable
puts 'RuntimeError was raised now'
else
puts 'This runs if no exceptions were thrown at all'
ensure
puts 'This code always runs no matter what'
end
Functions
def sum(x, y)
x + y
end
Use parentheses when there are arguments, and omit parentheses when the method doesn’t accept any arguments.
Functions and blocks returns the value of the last statement.
Parentheses are optional when calling methods. Parameters are separated by commas.
sum 3, 4
sum sum(3, 4), 5 # resolve ambiguity
To use a block as parameter, use &
:
def guests(&block)
block.call 'some_argument'
end
To pass arbitrary number of parameters, use *
. These parameters will be converted into an array:
def guests(*array)
array.each { |guest| puts guest }
end
Yield
All methods have an implicit, optional block parameter which can be called with the yield
keyword. The yield
keyword calls the code supplied in the block.
def surround
puts "{"
yield
puts "}"
end
surround { puts 'hello world' }
Function call to surround replaces the block into the yield
keyword.
Classes
- Definition:
class Human # something end
- Class variables, shared by all instances of this class and all its descendants:
@@species = 'Human'
- Constructor is a method called
initialize
. Instance variables are defined here using@name
. - Getters and setters:
```ruby
Basic setter method
def name=(name) @name = name end
Basic getter method
def name @name end
However, getters and setters can be generated using `attr_accessor :name`, or individually using `attr_reader :name` and `attr_writer :name`. Variables after `attr_accessor` keyword can be chained together using commas.
* Class methods: use `self` keywords like `def self.say(msg)`.
* Instantiate a class object: `jim = Human.new('Jim')`.
## Singleton classes
The singleton class of an object is a class that holds methods for only that instance. To define it, using `class << <object>`.
Often, singleton class are defined like this:
class C
class << self
# ...
end
end
This allows definition of class methods without the `self` keywords, and they are grouped into the singleton class for better readability.
## Variable scope
* Global: `$var`
* Instance: `@var`
* Class: `@@var`
* Constant: `Var`
Note `var` and `$var` is two different variables.
## Accessibility
By default, methods are public. Access modifier (`private`, `protected`, `public`) continues until the end of the scope, or another access modifier pops up. So a modifier will last to the end of the class if no other modifiers pop up.
A protected method can be called from a class or descendant class instances, but also with another instance as its receiver.
A private method cannot be called outside the instance.
## Modifiability
Ruby class are open. You can redefine the class and adding, changing or removing things of that class.
To open a class, simply redefine it as normal class definition.
* Adding: simply define it.
* Changing: use `alias <new_name> <old_name>` to change name.
* Removing a method: use `remove_method :<my_method>`.
## Inheritance
```ruby
class Children < Parent
end
Note class variables are shared between base class and all child classes; but instance variable is not shared.
To call the overloaded method in parent class from child class, use super
keyword.
class Foo
def foo
"#{self.class}#foo"
end
end
class Bar < Foo
def foo
"Super says: #{super}"
end
end
Method naming conventions
- Methods that answer questions (returns
true
orfalse
) end in question marks. - Methods that are potentially dangerous end with exclamation marks.
Module
A module is a collection of methods and constants.
module ModuleExample
def foo
'foo'
end
end
To use the module, use include
or extend
keyword:
class Person
include ModuleExample
end
class Book
extend ModuleExample
end
include
modules binds the methods to objects of the class.extend
modules binds the methods to the class.
Modules can be nested. You can physically put inner module inside the outer module, or use ::
like .
in Java provided the outer modules are already defined.
Embedded Ruby
Ruby provides a program called ERB (Embedded Ruby). It allows you to put Ruby codes inside an HTML file. ERB reads along, word for word, and then at a certain point, when it encounters a Ruby code embedded in the document, it starts executing the Ruby code.
The syntax is similar as JSP.
You need to know only two things to prepare an ERB document:
- If you want some Ruby code executed, enclose it between
<%
and%>
. - If you want the result of the code execution to be printed out, as a part of the output, enclose the code between
<%=
and%>
.
<% page_title = "Demonstration of ERB" %>
<% salutation = "Dear programmer," %>
<html>
<head>
<title><%= page_title %></title>
</head>
<body>
<p><%= salutation %></p>
<p>This is an example of how ERB fills out a template.</p>
</body>
</html>