[ LiB ] | ![]() ![]() |
The most important thing to remember when starting out is that Ruby is considered to be a pure object-oriented scripting language. Being object-oriented means that any data itself is treated like an object. For instance, integers in Ruby automatically become objects, instances of the number class.
The Ruby language is considered similar to perl and PHP. Ruby resembles perl in a lot of ways. For instance, there are shortcuts to globals using funny characters, like $&, $<, $>, and $DEBUG. If you're familiar with string handling and pattern matching in Perl, you will find Ruby's handlings of those same problems to be similar.
One important difference between Ruby and other object-oriented languages: Ruby only supports single inheritance; most OOP languages have multiple inheritance. This means that in Ruby, sub-classes can only be derived from one parent.
A few lingual notes right off the bat. Each expression in Ruby generally takes up one line. There is no need for line terminations in Ruby. Semicolons can be used at the end of a line statement for style, but they aren't necessary. Ruby will recognize when a new line comes along, so you can end a statement by simply hitting Return. Expressions can also be grouped with parentheses.
Comments in Ruby begin with the pound sign.
# This is a comment. # The interpreter ignores me
Comments can also be embedded between =begin and =end commands; the interpreter will also skip anything in between them:
=begin This is a comment The interpreter ignores me =end
Without the equal signs, begin and end take the form of a block expression, most likely to be seen in an exception:
begin # This is a block # There are normally expressions within end
Ruby supports these concepts, called blocks, which are designated in a number of different ways. Basically everything within a do and an end is a block. Blocks can also be designated with curly brackets, like so:
do | this_is_a_block | end {this_is_another_block}
A special Ruby command called yield can call code blocks and evaluate them. yield evaluates the block given to the current method with arguments (if no argument is given, it uses nil). The argument assignment to the block parameter is done just like a multiple assignment.
As Ruby is an object-oriented language, it may be useful to define some object-oriented terms. An object is a container that holds variables and functions that are specific to itself. Objects are created by classes, and are synonymous with class instances. Classes are like object factories. They combine an object template with its methods. Methods are chunks of code that return a value of some sort (see Figure 9.2).
In practice, objects, classes, and methods are combined together. One example of this is that objects are created by calling classes with their constructor methods.
In Ruby, classes take on the following form:
Class MyClass() def initialize() end def MyMethod1 end # Other Expressions # Mayhap a CONSTANT end
The def expressions inside of MyClass are actually methods:
Def MyMethod (arguments) expression end
A class instance of MyClass (that is, a MyClass object) can be created by calling the MyClass constructor, initialize. An initialize method has special meaning in Ruby; it will automatically link up with a new method call. So, to create a class instance of MyClass, just type
MyObject = MyClass.new()
Once MyObject has been created, all of MyClass's methods are available to it:
MyObject.MyMethod1
Ruby has a number of standard built-in classes and methods. Many of the common classes are listed in Table 9.2, and common methods are listed in Table 9.3.
Classes | Domain |
---|---|
Array | Ordered collection of objects |
Bignum | Holds integers outside the range of Fixnum |
Binding | Encapsulate execution context |
Class | Base class for all classes |
Continuation | Objects generated by kernel call that hold a return address and execution context |
Dir | Represents directories |
Exception | Carries exception information |
FalseClass | Base class for logically false |
File | Abstraction of any file object |
File::Stat | Common status information for file objects |
Fixnum | Holds integer values |
Float | Represents real numbers |
Hash | Collection of key value pairs |
Integer | Base class for Bignum and Fixnum |
IO | Basis for all input and output |
MatchData | Type of the special $~ variable for encapsulating pattern matches |
Method | Base class for method objects |
Module | Base class for module objects |
NilClass | Base class for nil |
Numeric | Base type for Float, Fixnum, and Bignum |
Object | Parent class for all classes |
Proc | Parent for object blocks of code that are bound to a set of local variables |
Range | An interval with a start and end |
Regexp | Holds regular expressions |
String | Holds byte sequences |
Struct | Bundles attributes together |
Struct::Tms | Holds information on process times |
Symbol | Object that represents a Ruby name |
Thread | Parent for thread objects |
ThreadGroup | For keeping 9-track of threads as a group |
Time | Abstraction of dates and times |
TrueClass | Base class for logically true |
Method | Description/What It Does |
---|---|
'str | Performs str by a subshell |
Array | Converts given argument to an array |
at_exit | For cleaning up when the interpreter exits |
autoload | Specifies a file to be loaded using require |
binding | Returns data structure of a binding |
caller | Returns the information of the current call |
catch | Executes a throw/catch block |
chop | Removes last character of a value |
chomp | Removes a line from a value |
eval | Evaluates the given expression as a Ruby program |
exec | Executes the given command as a subprocess |
exit | Exits immediately |
exit! | Exits immediately and ignores any kind of exception handling |
fail | Raises exceptions |
Float | Converts given argument to a float |
fork | Forks child and parent processes |
format | Returns a string in the given format |
gets | Reads a string from standard input |
global_variables | Returns the list of all the global variable names defined in the given program |
gsub | Searches for a pattern in a string, and if the pattern is found, makes a copy of the string with the pattern replaced with a given argument |
gsub! | Searches for a pattern in a string, and if the pattern is found, replaces the pattern with the given argument. |
Integer | Converts given argument to an integer |
iterator? | Returns true if called from an iterator |
lambda | Returns newly created procedure object from the block |
load | Loads and evaluates the Ruby program in the file |
local_variables | Returns the list of all the local variable names defined in the current scope |
loop | Loops until terminated |
open | Opens a file and returns a file object associated with the file |
p | Prints given object to the stdout |
Prints arguments | |
printf | Prints arguments in a given format |
proc | Returns newly created procedure object from the block |
putc | Writes a given character to the default output |
raise | Used for raising exceptions |
rand | Returns a j-random number greater than or equal to 0 and less than the given value |
readline | Reads a string from standard input, raises exception at the end of a file |
readlines | Returns an array containing the read lines |
require | Used to load modules |
select | Calls select to reads, writes, excepts, and timeout system calls |
sleep | Causes script to sleep for a given amount of seconds |
split | Splits a string at the given string |
String | Converts given argument to a string |
sprintf | Returns a string in the given format |
srand | Sets the j-random number seed for rand |
sub | Searches a string held in $_ for a pattern and makes a copy that replaces the first occurrence with given argument |
sub! | Searches a string held in $_ for a pattern and replaces the first occurrence with given argument |
syscall | Used to make system calls |
system | Runs given command in a subprocess |
test | Performs a file test |
throw | Executes a throw/catch block |
trace_var | Sets the hook to a given variable that is called when the value of the variable is changed |
trap | Specifies the signal handler for a signal |
untrace_var | Deletes hooks set by trace_var |
Obviously, Ruby supports inheritance. Inheritance allows classes to inherit functionality from each other. A parent class in this sort of relationship is called a super class, and the child class is called a sub class. Sub classes are defined as children by the less than (<) symbol:
MySubClass < MyParentClass def MyMethod (arguments) expression end
Ruby also supports a number of other OOP concepts, such as mixins, which simulate multiple inheritance in Ruby's single parent system); singletons, which provide a way to override object creation; and overloading, which is when method calls can be overwritten by new definitions.
Ruby is case-sensitive, and identifiers can be composed of letters of the alphabet, decimals, or the underscore character. The standard language types include strings, constants, ranges, and numbers.
All variables and constants in Ruby point at an object. When a variable is assigned or initialized, the object that the variable is referencing is also assigned. Variables in Ruby are either global variables that begin with the $ character, instance variables that begin with an @ character, class variables that start with @@, constants that are all uppercase letters, local variables that are all lowercase letters, or class constants that are defined within certain classes or modules. There are also a few special variables in Ruby. All of these Ruby variables are outlined in Table 9.4.
Variable | Description |
---|---|
__FILE__ | Current source filename |
__LINE__ | Current line number in the source file |
@variable | Instance variable |
@@ | Class variable |
$variable | Global variable |
variable | Standard variable |
VARIABLE | Constant variable |
false | Instance of the class FalseClass (i.e. false) |
nil | Instance of the class NilClass (i.e. false) |
self | Receiver of the current method |
true | Instance of the class TrueClass (that is, true) |
Setting a variable is fairly intuitive; it is done like so:
myvariable = "My String\n"
Set a global variable like this:
$myvarible = "My String\n"
Set class variables like this:
@@myvariable = "My String\n"
And so on.
In Ruby, a handful of reserved words cannot be used for variable names. These include the following:
BEGIN
class
ensure
nil
self
when
END
def
false
not
super
while
alias
defined
for
or
then
yield
and
do
if
redo
true
begin
else
in
rescue
undef
break
elsif
module
retry
unless
case
end
next
return
until
In Ruby, strings are 8-bit byte sequences. They normally hold characters, but can also hold binary data. A string object is actually an instance of the class String.
When playing with strings, one should know that Ruby differentiates between single and double quotes. Notice the difference between
print "string\n"
and
Print 'string\n'
When the two lines of code above run within the interpreter, Ruby recognizes the \n as an escape sequence on the first line and not on the second.
The explanation for this is that strings can begin and end with either single or double quotation marks, but whether you use single or double quotation marks depends on the situation. Expressions in double quotes are generally subject to backslash escape characters, and single quotes are not (except for \ and \\). If you need a string to not be subject to any escape sequences, including the \ or \\, then you must begin the expression with a percentage % sign.
The String class has many methods (close to 100) associated with it. Since Ruby must often handle strings, it makes sense that it would have many standard methods for performing standard actions on strings.
Common escape sequences are listed in Table 9.5.
Sequence | Meaning |
---|---|
\ | Add octal value character |
\a | Bell |
\b | Backspace |
\cx | Control x |
\C-x | Control x |
\e | Escape |
\f | Form feed |
\n | Newline |
\r | Carriage return |
\s | White space |
\t | Tab |
\v | Vertical tab |
\x | Add hexadecimal value character |
\M-x | Meta x |
\M-\C-x | Meta control x |
Regular expressions are the tools that Ruby uses for pattern matching and other common functions against strings. Not only do commands exist for matching patterns, but there are also commands for anchoring patterns, repeating searches, choosing between alternate patterns, grouping, and substitution. Common Ruby expressions are listed in Table 9.6.
Expression | Description |
---|---|
$! | Exception information message (set by raise) |
$@ | Backtrace of the last exception |
$& | The string matched by the last successful pattern match in this scope |
$` | The string preceding whatever was matched by the last successful pattern match in the current scope |
$' | The string following whatever was matched by the last successful pattern match in the current scope |
$+ | The last bracket matched by the last successful search pattern |
$1, $2... | Contains the subpattern from the corresponding set of parentheses in the last successful pattern matched |
$~ | Information about the last match in the current scope |
$= | Flag for case insensitive |
$/ | Input record separator |
$\ | Output record separator |
$, | Output field separator |
$; | Default separator for String#split |
$. | The current input line number of the last file that was read |
$< | The virtual concatenation file of the files given by command-line arguments. Stdin by default |
$> | Default output for print, printf.s by default |
$_ | The last input line of string by gets or readline |
$0 | Contains the name of the file containing the Ruby script being executed |
$* | Command-line arguments given for the script |
$$ | The process number of Ruby running this script |
$? | The status of the last executed child process |
$: | The array contains the list of places to look for Ruby scripts and binary modules by load or require |
$" | The array contains the module names loaded by require |
$DEBUG | Status of the -d switch |
$FILENAME | Same as $<.filename or stdin filename |
$LOAD_PATH | The alias to the $: |
$stdin | The current standard input |
$stdout | The current standard output |
$stderr | The current standard error output |
$VERBOSE | The verbose flag, which is set by the -v switch to the Ruby interpreter |
$-0 | The alias to the $/ |
$-a | True if option -a is set |
$-d | The alias to the $DEBUG |
$-F | The alias to the $;. \ |
$-i | In in-place-edit mode |
$-I | The alias to the $: |
$-l | True if option -lis set |
$-p | True if option -pis set |
$-v | The alias to the $VERBOSE |
Like variables, constants hold references to objects and are created when they are first assigned. Unlike in other languages, constants can be changed in Ruby, although a change fires off a warning from the interpreter.
Constants that are defined within a class or module are accessible from within the class or module. Outside of the class or module, the scope operator (::) can be used to access them. Ruby also has a number of pre-defined constants that are global in scope; these are listed in Table 9.7.
Constant | Description |
---|---|
ARGF | Alias to $< |
ARGV | Alias to $* |
DATA | The file object of the script |
ENV | Contains current environment variables |
FALSE | False |
NIL | Nil |
RUBY_RELEASE_DATE | Ruby release date string |
RUBY_PLATFORM | Ruby platform identifier |
STDIN | Standard input or $stdin |
STDOUT | Standard output or $stdout |
STDERR | Standard error or $stderr |
TRUE | True |
VERSION | Ruby version string |
Ranges are used in Ruby to express sequences such as one through ten or A to Z. Ranges come with a number of useful methods for iterating over themselves or testing their contents. The .. operator is used to create a range type object:
myrange = 1..10
Ranges are probably most often used to create arrays but are also sometimes used in conditional statements.
Ruby deals primarily with integers and floating-point numbers. Smaller numbers are objects of the Fixnum class and large numbers are objects of the Bignum class. Ruby understands octal, binary, and hexadecimal numbers. Ruby numbers are outlined in Table 9.8.
Number | Type |
---|---|
10 | Integer |
-10 | Signed integer |
10.10 | Floating point number |
0xffff | Hexadecimal integer |
0b01011 | Binary integer |
0377 | Octal integer |
As all numbers are objects, you may find them used in Ruby in what would be unusual ways in other languages. numbers in Ruby will respond to messages and built-in methods that do iterations.
Ruby has a number of operators, including the standard +, -, /, and *. Again, most operators are method calls. Following is a list of the Ruby operators, from highest to lowest level of precedence (the operators are further outlined in Table 9.9):
::
**
-(unary) +(unary) ! ~
/ %
+ -
<< >>
&
| ^
>= < <=
<=> == === != =~ !~
&&
||
.. ...
=(+=, -=...)
not
and or
Operator | Use |
---|---|
== | Tests for equality |
=== | Tests equality in a case statement |
<=> | Compares two values |
<, <=, >=, > | Less than, greater than, etc. |
=~ | Regular expression pattern match |
+= 1 | Increment by 1 |
-=1 | Decrement by 1 |
&& | Logical and |
|| | Logical or |
! | Logical not |
!= | Not equal |
.. | Range |
:: | Scope resolution |
and | Logical and |
eql? | Compares type and value |
equal? | Compares object ID |
not | Logical not |
or | Logical or |
Assignments are made in Ruby using the powerful equal sign:
Hello = 'Hi'
Multiple assignments can be made by using commas and equal signs:
1,2,3 = 'you', 'me' , 'I'
Ruby has a number of standard control structure expressions for controlling program flow. These include if, then, unless, else, while, until, for, and case. These controls are supported by a number of operators in addition to the standard ==, <, <=, >, >=, and =. These operators are listed in Table 9.9.
The chain of if… then… else… is one of the most common control structures, and in Ruby the syntax appears as follows:
if this_is_true [then] do_this [elsif this_is_true_instead [then] do_this_Instead] [else do_this_if_all_else_fails] end
A typical unless control structure looks almost identical:
unless this_is_true [then] do_this [else do_this_instead] end
The case statement in Ruby is much like a quicker-coding if statement when multiple choices are available. The case statement makes a comparison between the expression given and any number of expressions (or ranges) that are set after while keywords:
case $my_case_statement when 0 .. 8-n-1 "case_1" when 2 .. 3 "case_2" when 4.. 20 "case_3" when Square "case_4_sides" else "case_5" end
The until construct and the while construct are also very similar:
# First until until this_is_true do_this end #Then while while this_is_true do_this end
The for looping construct is used to iterate over any object that can respond to iteration, namely arrays or ranges. The following example prints everything listed in the first argument given:
for i in [1, 2, 3] print I, " " end
There are a few useful commands that can be used in loops (and in blocks), including the following:
break. Terminates the immediately enclosing loop.
next. Skips to the end of the loop.
redo. Repeats the current loop from the start without re-evaluating the condition.
retry. Repeats the current loop.
return. Exits the method/loop/block with the return value or an array of return values.
For handling exceptions Ruby has a built-in raise command. raise can create a runtime error, send messages, create an exception of type error_type, and even send traceback information in the format given by a variable caller function. Examples:
raise "This is an error" raise SyntaxError, "invalid syntax" raise SyntaxError.new("new error type")
Arrays are instances of the class Array, and they hold collections of object references. An array can be created by simply assigning a number of values as you would with a variable:
$MyArray = ['Hello', 'I', 'love', 'you']
Each value in the array can then be accessed numerically:
print $MyArray[0] print $MyArray[1] print $MyArray[2] print $MyArray[2]
Hashes are also instances of the Hash class, and are also collections of object references. Hashes are like arrays, only within curly brackets and with key => value pairs:
$MyHash = {'a'=>1, 'b'=>2, 'c'=>3, 'd'=>4}
Then hash values can be referenced by their keys:
print $MyHash['a'] print $MyHash['b'] print $MyHash['c'] print $MyHash['d']
Ruby has built-in exception classes for raising exceptions, each of which has its own message string and stack backtrace. Exception code is normally put into begin and end blocks, and is handled by a rescue clause, like this:
begin # code that does something rescue Exception $stderr.print "error message" raise end
The raise method is used in this case to raise the current exception, but it can also be used to create a unique exception and error message:
if MyError == true raise MyError, "My Unique Error", caller end
Catch and throw are also used when execution must be abandoned completely. The catch command creates a block of code that executes normally until a throwis encountered. When Ruby hits a throw, it goes back up the call stack looking for the matching catch, rewinds to that point, and terminates the block. Optionally, when Ruby jumps back up the stack, another throw parameter can be sent upwards, causing Ruby to continue bouncing upward:
catch (:MyCatch) do while (1) throw :MyCatch unless all_is_well end end
Modules are groups of methods, classes, and constants (see Figure 9.3). As programs grow bigger and bigger, it becomes necessary for most languages to segregate bits of functionality and similar functions. Modules are Ruby's way of organizing large batches of code.
Modules can be defined fairly easily with the module command:
module MyModule SOME_CONSTANT=1 ANOTHER_CONSTANT=2 def Some_Class # class expressions end end
Save the module into a file called MyFile.rb, and Ruby will have the option of loading the additional module by using require or load:
Load "MyFile.rb" Require "MyModule"
Ruby comes with a number of modules for adding extra functionality to your program already built in (see Table 9.10).
Module | Use/Description |
---|---|
Comparable | Comparing objects |
Enumerable | Traversal and searching methods |
Errno | Mapping OS system errors |
FileTest | File test operations |
GC | Garbage collection interface |
Kernel | Objects can access kernel module |
Marshal | Ability to serialize objects |
Math | Basic trigonometry and transcendental functions |
ObjectSpace | Added GC functionality for iterating over all living objects |
Precision | Number precision |
Process | Manipulate processes |
Libraries are collections of modules and classes, and Ruby has a wealth of them. Table 9.11 lists a few of the more common libraries and their general purposes. These libraries are written in Ruby itself and are found in the /lib/ folder of the distribution.
Library | Purpose/Description |
---|---|
Delegate | For building delegate-type objects |
English | Includes the English library file |
Observer | For communication between objects |
Profile | For code profiling, prints summary of system calls to $stderr |
Network | Ruby provides a number of socket-level access classes, including socket, BasicSocket, IPSocket, TCPSocket, SOCKSocket, TCPServer, and UDPSocket |
Singleton | For ensuring that only one instance of a particular class is created |
Timeout | For timing code blocks |
[ LiB ] | ![]() ![]() |