Since I’m learning Ruby on Rails, I feel the need to know the basic syntax of the language. So here is my own primer guide to basic Ruby syntax. The guide was wrote largely based on the [[http://docs.huihoo.com/ruby/ruby-man-1.4/syntax.htmll|original manua]] by Ruby’s author, [[http://en.wikipedia.org/wiki/Yukihiro_Matsumoto|Yukihiro Matsumoto]]
===== Ruby =====
Ruby is case-sensitive. Whitespace characters are space, tab, vertical tab, backspace, carriage return, and form feed. Newlines works as whitespace only when expressions obviously continues to the next line.
==== String literals ====
"remeber to escape \" and \\ #{expression_substituted}" # streng enquoted with doublequote is subjected to expression substitution
'remember to escape \' and \\ #{expression_not_substituted}' # streng enquoted with doublequote is not evaluated
%q!Some string with "double quote" and 'single quote'! # equivalent to '' and don't have to escape double quote or single quote
%Q('Some string with "double quote" and \'single quote\' and back parenthesis \) ') # equivalent to "" and don't have to escape double quote or single quote
%!Some string with "double quote" and 'single quote'! # equivalent to "" and don't have to escape double quote or single quote
==== Expression subtitiion in strings ====
"hello my name is #{$name}" # sub #{$name} with $name
$ and @ variables don’t need to be enclosed within #{}. The # only has special meanings when it’s followed by {,@, and $
==== Regular Expressions ====
%r/STRING/
/regexp/
* **Modifiers**
/regexp/i # case insensitive
/regexp/x # extended expr, no whitespaces and comments are allowed
/regexp/p # POSIX mode, newlines are treated as normal charactor
==== Variables ====
$var # global
@var # instance variable of self
VAR # constant
SomeClass::VAR # constant within a class
var or _var # local variable
=== Pseudo Variables ===
* self
* nil
* true
* false
* __FILE__ : current source file
* __LINE__ : current line
=== Array ===
* [1,2,3]
* %w(foo bar baz): create a new string, space-separated array, equivalient to [”foo”, “bar”, “baz”]
=== Hash ===
* {expr1 => exprA, expr2 => exprB }
===== Method invocation =====
* **method(args1, arg2)**
* **method(*array)** is equivalent to **method(array_member1, array_member2, …)**. The * expands the argument array.)
===== Operators =====
+, -, *, /, %, **, &, |, ^, <<, >>, &&, ||
foo += 5
foo, bar, baz = 1, 2, 3
foo, bar = 1 # foo = 1; bar = nil
foo,*bar = 1, 2, 3 # equivalent to foo = 1; bar = [2, 3] ( the * multiple assignment is used to assign to an array)
===== Control Structure =====
**false** and **nil** are false, everything else are true.
* If statement
if expr [then]
expr...
[elsif expr [then]
expr...]...
[else
expr...]
end
* unless
unless expr [then]
expr...
[else
expr...]
end
=== if and unless modifier ===
* expr1 **if** expr2: if expr2 is true, execute expr1
* expr1 **unless** expr2: if expr2 is false, execute expr1
=== case ===
* case comparison is via the === operator
case expr
[when expr [, expr]...[then]
expr..]..
[else
expr..]
end
case $age
when 0 .. 2
"baby"
when 3 .. 6
"little child"
when 7 .. 12
"child"
when 12 .. 18
# Note: 12 already matched by "child"
"youth"
else
"adult"
end
==== Range ====
* expr1 .. expr2 (similar to awk)
* expr1 … expr2 (similar to sed)
==== Loop ====
while expr [do]
#code here
end
until expr [do]
#code here
end
=== while and until modifier ===
expr1 while expr2 # keep evaluating expr1 while expr2 is true.
expr1 untill expr2 # keep evaluating expr1 until expr2 is true
begin expr1 until expr2 # evaluating expr1 at least 1 time until expr2 is true
==== Iterators ====
* [1,2,3].each do |i| print i*2, “\n” end
* [1,2,3].each{|i| print i*2, “\n”}
==== For (similar to foreach) ====
for lhs... in expr [do]
expr..
end
* Example: for i in [1, 2, 3]
print i*2, "\n"
end
There are 2 special keywords that can be used in the loop body: **next** (jump to next iteration of the inner-most loop) and **redo** (restart the current iteration of the most inner-most loop without checking loop condition)
==== Raising Errors ====
* Raise syntax
raise # raise general exception
raise message_or_exception
raise error_type, message
raise error_type, message, traceback
* Examples
raise "you lose" # raise RuntimeError
# both raises SyntaxError
raise SyntaxError, "invalid syntax"
raise SyntaxError.new("invalid syntax")
raise # re-raise last exception
* $! contains the exception and $@ contains the position in source file.
==== begin block ====
**begin** is different from the uppercase **BEGIN**, which has a totally different meaning
begin
expr1..
[rescue [error_type,..]
expr2..]..
[else
expr3..]
[ensure
expr4..]
end
If exception occurs in **expr1**, **rescue** will execute **expr2**. The matching of **error_type** is done by **kind_of?**. **else** clause has to follow after **rescue** and is executed if no exception occurs in **expr1**. And example:
begin
do_something # exception raised
rescue
# handles error
retry # restart from beginning
end
for i in 1..5
retry if some_condition # restart from i == 1
end
# user defined "until loop"
def UNTIL(cond)
yield
retry if not cond
end
==== BEGIN and END blocks ====
BEGIN {
...
}
BEGIN registers initializing blocks in the appearing order, which will then get executed before any statement in the file. BEGIN has its own internal scope (don’t share local variables with outer scopes) and has to appear at toplevel.
END {
...
}
END register finalizing blocks. END blocks share their local variables. The END statement can only appear at the toplevel. Also you cannot cancel finalize routine registered by END.
==== Class ====
class Classname < SuperClass
expr..
end
class SingleTonClassname << SuperClass
expr..
end
==== Module ====
module Foo
def test
:
end
:
end
==== Method ====
Method has to be defined before it is invoked. It cannot be nested. Method’s return can be defined explicitly with “return”, or implicitly using the last evaluated expression
def fact(n)
if n == 1 then
1
else
n * fact(n-1)
end
end
Method can be declared private inside the function form. If Method is declared outside the class definition, it’s marked private by default. Method declared within class definition is marked public by default.
==== Singleton-method ====
def foo.test
print "this is foo\n"
end
The singleton-method definitions can be nested and are inherited to subclasses. Singleton-method acts as typical class’s method in other OOP languages.
==== alias, undef, and defined? ====
alias method-name method-name
alias global-variable-name global-variable-name
Aliasing numbered global variables is forbidden.
=== undef ===
undef method_name
Used to cancel method definition.
=== defined? ===
defined? expr
If expr is not defined, return false, otherwise return a string describing the kind of expression.
Congratulations! You have just won a new blog reader
.. really delicious post, Mike.