Language Structure

[ LiB ]

Language Structure

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.

Objects, Classes, and Methods

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).

Figure 9.2. Objects and methods derived from a class

graphic/09fig02.gif


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.

Table 9.2. Built-in Ruby Classes

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 track of threads as a group

Time

Abstraction of dates and times

TrueClass

Base class for logically true


Table 9.3. Built-in Ruby Methods

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

print

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 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 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.

Language Types

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.

Table 9.4. Ruby Variables

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

Strings

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.

Table 9.5. Common Ruby Escape Sequences

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

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.

Table 9.6. Common Ruby Expressions

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


Constants

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.

Table 9.7. Ruby Global Pre-Defined Constants

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

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.

Numbers

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.

Table 9.8. Ruby Numbers

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):

  1. ::

  2. **

  3. -(unary) +(unary) ! ~

  4. / %

  5. + -

  6. << >>

  7. &

  8. ^

  9. >= < <=

  10. <=> == === != =~ !~

  11. &&

  12. .. ...

  13. =(+=, -=...)

  14. not

  15. and or

Table 9.9. Commonly Used Ruby Operators

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' 

Control Structures

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 .. 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 and Hashes

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'] 

Exceptions

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 throw is 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

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.

Figure 9.3. Modules hold groups of classes and methods

graphic/09fig03.gif


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).

Table 9.10. Pre-Defined Ruby Modules

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

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.

Table 9.11. Ruby Libraries

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 ]


Game Programming with Pyton, Lua and Ruby
Game Programming with Pyton, Lua and Ruby
ISBN: N/A
EAN: N/A
Year: 2005
Pages: 133

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net