Ruby
Ruby
Audience
This tutorial has been prepared for beginners to help them understand the basic
to advanced concepts related to Ruby Scripting languages.
Prerequisites
Before you start practicing with various types of examples given in this tutorial,
we are making an assumption that you are already aware of computer programs
and programming languages in general.
Table of Contents
About the Tutorial ..................................................................................................................................... i
Audience .................................................................................................................................................... i
Prerequisites .............................................................................................................................................. i
Copyright & Disclaimer .............................................................................................................................. i
Table of Contents ...................................................................................................................................... ii
1. OVERVIEW ............................................................................................................................ 1
Features of Ruby ....................................................................................................................................... 1
Tools You Will Need .................................................................................................................................. 2
What is Next? ........................................................................................................................................... 2
3. SYNTAX ............................................................................................................................... 12
Whitespace in Ruby Program .................................................................................................................. 12
Line Endings in Ruby Program ................................................................................................................. 12
Ruby Identifiers ...................................................................................................................................... 13
ii
iii
6. OPERATORS ........................................................................................................................ 36
Ruby Arithmetic Operators ..................................................................................................................... 36
Ruby Comparison Operators ................................................................................................................... 37
Ruby Assignment Operators ................................................................................................................... 38
Ruby Parallel Assignment........................................................................................................................ 39
Ruby Bitwise Operators .......................................................................................................................... 39
Ruby Logical Operators ........................................................................................................................... 40
Ruby Ternary Operator ........................................................................................................................... 41
Ruby Range Operators ............................................................................................................................ 41
Ruby defined? Operators ........................................................................................................................ 42
Ruby Dot "." and Double Colon "::" Operators ........................................................................................ 43
Ruby Operators Precedence.................................................................................................................... 44
7. COMMENTS ........................................................................................................................ 47
Ruby Multiline Comments ...................................................................................................................... 47
9. LOOPS ................................................................................................................................. 54
Ruby while Statement ............................................................................................................................ 54
Ruby while modifier ............................................................................................................................... 55
Ruby until Statement.............................................................................................................................. 56
iv
11. BLOCKS................................................................................................................................ 69
The yield Statement ............................................................................................................................... 69
Blocks and Methods ................................................................................................................................ 71
BEGIN and END Blocks ............................................................................................................................ 72
vi
viii
ix
xi
xii
xiii
xiv
1. OVERVIEW
Ruby
Features of Ruby
Ruby has a clean and easy syntax that allows a new developer to learn
very quickly and easily.
Ruby is very much scalable and big programs written in Ruby are easily
maintainable.
Ruby support many GUI tools such as Tcl/Tk, GTK, and OpenGL.
Ruby has a rich set of built-in functions, which can be used directly into
Ruby scripts.
1
Ruby
Ruby 1.8.5
This tutorial will provide the necessary skills to create GUI, networking, and Web
applications using Ruby. It also will talk about extending and embedding Ruby
applications.
What is Next?
The next chapter guides you to where you can obtain Ruby and its
documentation. Finally, it instructs you on how to install Ruby and prepare an
environment to develop Ruby applications.
2. ENVIRONMENT SETUP
Ruby
Ruby Command Line Options : This chapter list out all the command
line options, which you can use along with Ruby interpreter.
Ruby
After having downloaded the Ruby archive, unpack it and change into the
newly created directory:
$ tar -xvzf ruby-1.6.7.tgz
$ cd ruby-1.6.7
If everything is fine, this should output the version of the installed Ruby
interpreter as shown above. You may have installed different version, so it
will display a different version.
Ruby
After having downloaded the Ruby archive, unpack it and change into the
newly created directory:
Click Next to move to the Important Information page of the wizard and
keep moving till Ruby installer completes installing Ruby.
You may need to set some environment variables if your installation has not
setup them appropriately.
If you use Windows 9x, add the following lines to your c:\autoexec.bat:
set PATH="D:\(ruby install directory)\bin;%PATH%"
Add your Ruby directory to the end of the Variable Value list and click
OK.
Add .RB and .RBW to the Variable Value list and click OK.
If everything is fine, this should output the version of the installed Ruby
interpreter as shown above. You may have installed different version, so it
will display a different version.
Ruby
The interpreter can be invoked with any of the following options to control the
environment and behavior of the interpreter.
Option
Description
-a
-c
-C dir
-d
-F pat
-e prog
-h
-i [ ext]
-I dir
-K [ kcode]
-l
-n
Places code within an input loop (as in while gets; ... end).
-0[ octal]
-p
Ruby
-r lib
-s
-T [level]
-v
-w
-x [dir]
-X dir
-y
--copyright
--debug
--help
--version
Displays version.
--verbose
--yydebug
Ruby
Single character command-line options can be combined. The following two lines
express the same meaning:
$ruby -ne 'print if /Ruby/' /usr/share/bin
Description
DLN_LIBRARY_PATH
HOME
LOGDIR
PATH
RUBYLIB
RUBYLIB_PREFIX
RUBYOPT
Ruby
RUBYPATH
RUBYSHELL
For Unix, use env command to see a list of all the environment variables.
HOSTNAME=ip-72-167-112-17.ip.secureserver.net
RUBYPATH=/usr/bin
SHELL=/bin/bash
TERM=xterm
HISTSIZE=1000
SSH_CLIENT=122.169.131.179 1742 22
SSH_TTY=/dev/pts/1
USER=amrood
JRE_HOME=/usr/java/jdk/jre
J2RE_HOME=/usr/java/jdk/jre
PATH=/usr/local/bin:/bin:/usr/bin:/home/guest/bin
MAIL=/var/spool/mail/guest
PWD=/home/amrood
INPUTRC=/etc/inputrc
JAVA_HOME=/usr/java/jdk
LANG=C
HOME=/root
SHLVL=2
JDK_HOME=/usr/java/jdk
LOGDIR=/usr/log/ruby
LOGNAME=amrood
SSH_CONNECTION=122.169.131.179 1742 72.167.112.17 22
LESSOPEN=|/usr/bin/lesspipe.sh %s
RUBYLIB=/usr/lib/ruby
G_BROKEN_FILENAMES=1
9
Ruby
_=/bin/env
If you are working on Windows machine, then you can use any simple text
editor like Notepad or Edit plus.
VIM (Vi IMproved) is a very simple text editor. This is available on almost
all Unix machines and now Windows as well. Otherwise, your can use your
favorite vi editor to write Ruby programs.
Ruby
What is Next?
We assume now you have a working Ruby Environment and you are ready to
write the first Ruby Program. The next chapter will teach you how to write Ruby
programs.
11
3. SYNTAX
Ruby
Let us write a simple program in ruby. All ruby files will have extension .rb. So,
put the following source code in a test.rb file.
#!/usr/bin/ruby -w
Example
a + b is interpreted as a+b ( Here a is a local variable)
a
12
Ruby
Ruby Identifiers
Identifiers are names of variables, constants, and methods. Ruby identifiers are
case sensitive. It means Ram and RAM are two different identifiers in Ruby.
Ruby identifier names may consist of alphanumeric characters and the
underscore character ( _ ).
Reserved Words
The following list shows the reserved words in Ruby. These reserved words may
not be used as constant or variable names. They can, however, be used as
method names.
BEGIN
do
next
then
END
else
nil
true
alias
elsif
not
undef
and
end
or
unless
begin
ensure
redo
until
break
false
rescue
when
case
for
retry
while
class
if
return
while
def
in
self
__FILE__
defined?
module
super
__LINE__
13
Ruby
If the terminator is quoted, the type of quotes determines the type of the lineoriented string literal. Notice there must be no space between << and the
terminator.
Here are different examples:
#!/usr/bin/ruby -w
print <<EOF
This is the first way of creating
here document ie. multiple line string.
EOF
print <<"EOF";
# same as above
print <<`EOC`
# execute commands
echo hi there
echo lo there
EOC
I said foo.
foo
I said bar.
bar
This will produce the following result:
This is the first way of creating
her document ie. multiple line string.
This is the second way of creating
her document ie. multiple line string.
hi there
lo there
14
Ruby
I said foo.
I said bar.
Example
#!/usr/bin/ruby
BEGIN {
puts "Initializing Ruby Program"
}
This will produce the following result:
Initializing Ruby Program
This is main Ruby Program
15
Ruby
Example
#!/usr/bin/ruby
END {
puts "Terminating Ruby Program"
}
BEGIN {
puts "Initializing Ruby Program"
}
This will produce the following result:
Initializing Ruby Program
This is main Ruby Program
Terminating Ruby Program
Ruby Comments
A comment hides a line, part of a line, or several lines from the Ruby interpreter.
You can use the hash character (#) at the beginning of a line:
# I am a comment. Just ignore me.
Or, a comment may be on the same line after a statement or expression:
name = "Madisetti" # This is again comment
You can comment multiple lines as follows:
# This is a comment.
# This is a comment, too.
# This is a comment, too.
# I said that already.
16
Ruby
Here is another form. This block comment conceals several lines from the
interpreter with =begin/=end:
=begin
This is a comment.
This is a comment, too.
This is a comment, too.
I said that already.
=end
17
Ruby
Data Encapsulation
Data Abstraction
Polymorphism
Inheritance
These features have been discussed in the chapter Object Oriented Ruby.
An object-oriented program involves classes and objects. A class is the blueprint
from which individual objects are created. In object-oriented terms, we say that
your bicycle is an instance of the class of objects known as bicycles.
Take the example of any vehicle. It comprises wheels, horsepower, and fuel or
gas tank capacity. These characteristics form the data members of the class
Vehicle. You can differentiate one vehicle from the other with the help of these
characteristics.
A vehicle can also have certain functions, such as halting, driving, and speeding.
Even these functions form the data members of the class Vehicle. You can,
therefore, define a class as a combination of characteristics and functions.
A class Vehicle can be defined as:
Class Vehicle
{
Number no_of_wheels
Number horsepower
Characters type_of_tank
Number Capacity
Function speeding
{
}
Function driving
{
}
18
Ruby
Function halting
{
}
}
By assigning different values to these data members, you can form several
instances of the class Vehicle. For example, an airplane has three wheels,
horsepower of 1,000, fuel as the type of tank, and a capacity of 100 liters. In
the same way, a car has four wheels, horsepower of 200, gas as the type of
tank, and a capacity of 25 liters.
Local Variables: Local variables are the variables that are defined in a
method. Local variables are not available outside the method. You will see
more details about method in subsequent chapter. Local variables begin
with a lowercase letter or _.
Global Variables: Class variables are not available across classes. If you
want to have a single variable, which is available across classes, you need
19
Ruby
Example
Using the class variable @@no_of_customers, you can determine the number of
objects that are being created. This enables in deriving the number of
customers.
class Customer
@@no_of_customers=0
end
20
Ruby
21
Ruby
Here, statement 1 and statement 2 are part of the body of the method function
inside the class Sample. These statements could be any valid Ruby statement.
For example, we can put a method puts to print Hello Ruby as follows:
class Sample
def hello
puts "Hello Ruby!"
end
end
Now in the following example, create one object of Sample class and call hello
method and see the result:
#!/usr/bin/ruby
class Sample
def hello
puts "Hello Ruby!"
end
end
Ruby
#!/usr/bin/ruby
class Customer
@@no_of_customers=0
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
def total_no_of_customers()
@@no_of_customers += 1
puts "Total number of customers: #@@no_of_customers"
end
end
The display_details method contains three puts statements, displaying the
Customer ID, the Customer name, and the Customer address. The puts
statement will display the text Customer id followed by the value of the variable
@cust_id in a single line as follows:
puts "Customer id #@cust_id"
When you want to display the text and the value of the instance variable in a
single line, you need to precede the variable name with the hash symbol (#) in
the puts statement. The text and the instance variable along with the hash
symbol (#) should be enclosed in double quotation marks.
The second method, total_no_of_customers, is a method that contains the class
variable @@no_of_customers. The expression @@no_of_ customers+=1 adds 1
to the variable no_of_customers each time the method total_no_of_customers is
called. In this way, you will always have the total number of customers in the
class variable.
Now, create two customers as follows:
23
Ruby
class Customer
@@no_of_customers=0
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
24
Ruby
end
def total_no_of_customers()
@@no_of_customers += 1
puts "Total number of customers: #@@no_of_customers"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.display_details()
cust1.total_no_of_customers()
cust2.display_details()
cust2.total_no_of_customers()
Now, run this program as follows:
$ ruby main.rb
This will produce the following result:
Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Total number of customers: 1
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala
Total number of customers: 2
25
Ruby
Variables are the memory locations, which hold any data to be used by any
program.
There are five types of variables supported by Ruby. You already have gone
through a small description of these variables in the previous chapter as well.
These five types of variables are explained in this chapter.
$global_variable = 10
class Class1
def print_global
puts "Global variable in Class1 is #$global_variable"
end
end
class Class2
def print_global
puts "Global variable in Class2 is #$global_variable"
end
end
class1obj = Class1.new
class1obj.print_global
class2obj = Class2.new
class2obj.print_global
26
Ruby
Here $global_variable is a global variable. This will produce the following result:
NOTE: In Ruby, you CAN access value of any variable or constant by putting a
hash (#) character just before that variable or constant.
Global variable in Class1 is 10
Global variable in Class2 is 10
class Customer
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
end
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.display_details()
cust2.display_details()
27
Ruby
Here, @cust_id, @cust_name and @cust_addr are instance variables. This will
produce the following result:
Customer id 1
Customer name John
Customer address Wisdom Apartments, Ludhiya
Customer id 2
Customer name Poul
Customer address New Empire road, Khandala
class Customer
@@no_of_customers=0
def initialize(id, name, addr)
@cust_id=id
@cust_name=name
@cust_addr=addr
end
def display_details()
puts "Customer id #@cust_id"
puts "Customer name #@cust_name"
puts "Customer address #@cust_addr"
end
def total_no_of_customers()
@@no_of_customers += 1
28
Ruby
# Create Objects
cust1=Customer.new("1", "John", "Wisdom Apartments, Ludhiya")
cust2=Customer.new("2", "Poul", "New Empire road, Khandala")
# Call Methods
cust1.total_no_of_customers()
cust2.total_no_of_customers()
Here @@no_of_customers is a class variable. This will produce the following
result:
Total number of customers: 1
Total number of customers: 2
Ruby Constants
Constants begin with an uppercase letter. Constants defined within a class or
module can be accessed from within that class or module, and those defined
outside a class or module can be accessed globally.
Constants may not be defined within methods. Referencing an uninitialized
constant produces an error. Making an assignment to a constant that is already
initialized produces a warning.
29
Ruby
#!/usr/bin/ruby
class Example
VAR1 = 100
VAR2 = 200
def show
puts "Value of first Constant is #{VAR1}"
puts "Value of second Constant is #{VAR2}"
end
end
# Create Objects
object=Example.new()
object.show
Here VAR1 and VAR2 are constants. This will produce the following result:
Value of first Constant is 100
Value of second Constant is 200
Ruby Pseudo-Variables
They are special variables that have the appearance of local variables but
behave like constants. You cannot assign any value to these variables.
30
Ruby
Integer Numbers
Ruby supports integer numbers. An integer number can range from -230 to 230-1
or -262 to 262-1. Integers within this range are objects of class Fixnum and
integers outside this range are stored in objects of class Bignum.
You write integers using an optional leading sign, an optional base indicator (0
for octal, 0x for hex, or 0b for binary), followed by a string of digits in the
appropriate base. Underscore characters are ignored in the digit string.
You can also get the integer value, corresponding to an ASCII character or
escape the sequence by preceding it with a question mark.
Example
123
# Fixnum decimal
1_234
-500
# Negative Fixnum
0377
# octal
0xff
# hexadecimal
0b1011
# binary
?a
?\n
12345678901234567890 # Bignum
NOTE: Class and Objects are explained in a separate chapter of this tutorial.
Floating Numbers
Ruby supports integer numbers. They are also numbers but with decimals.
Floating-point numbers are objects of class Float and can be any of the following:
Example
123.4
1.0e6
# scientific notation
4E20
4e+20
String Literals
Ruby strings are simply sequences of 8-bit bytes and they are objects of class
String. Double-quoted strings allow substitution and backslash notation but
31
Ruby
single-quoted strings don't allow substitution and allow backslash notation only
for \\ and \'
Example
#!/usr/bin/ruby -w
Backslash Notations
Following is the list of Backslash notations supported by Ruby:
Notation
Character represented
\n
Newline (0x0a)
\r
\f
Formfeed (0x0c)
\b
Backspace (0x08)
\a
Bell (0x07)
32
Ruby
\e
Escape (0x1b)
\s
Space (0x20)
\nnn
\xnn
\cx, \C-x
Control-x
\M-x
Meta-x (c | 0x80)
\M-\C-x
Meta-Control-x
\x
Character x
Ruby Arrays
Literals of Ruby Array are created by placing a comma-separated series of object
references between the square brackets. A trailing comma is ignored.
Example
#!/usr/bin/ruby
ary = [
ary.each do |i|
puts i
end
This will produce the following result:
fred
10
3.14
This is a string
33
Ruby
last element
Ruby Hashes
A literal Ruby Hash is created by placing a list of key/value pairs between
braces, with either a comma or the sequence => between the key and the
value. A trailing comma is ignored.
Example
#!/usr/bin/ruby
hsh = colors = { "red" => 0xf00, "green" => 0x0f0, "blue" => 0x00f }
hsh.each do |key, value|
print key, " is ", value, "\n"
end
This will produce the following result:
green is 240
red is 3840
blue is 15
Ruby Ranges
A Range represents an interval.a set of values with a start and an end. Ranges
may be constructed using the s..e and s...e literals, or with Range.new.
Ranges constructed using .. run from the start to the end inclusively. Those
created using ... exclude the end value. When used as an iterator, ranges return
each value in the sequence.
A range (1..5) means it includes 1, 2, 3, 4, 5 values and a range (1...5) means it
includes 1, 2, 3, 4 values.
Example
#!/usr/bin/ruby
34
Ruby
(10..15).each do |n|
print n, ' '
end
This will produce the following result:
10 11 12 13 14 15
35
Ruby
6. OPERATORS
Ruby supports a rich set of operators, as you'd expect from a modern language.
Most operators are actually method calls. For example, a + b is interpreted as
a.+(b), where the + method in the object referred to by variable a is called with
b as its argument.
For each operator (+ - * / % ** & | ^ << >> && ||), there is a corresponding
form of abbreviated assignment operator (+= -= etc.).
Description
Example
a + b will give
30
a - b will give 10
a * b will give
200
b / a will give
2
b % a will give
0
**
Exponent - Performs
calculation on operators.
exponential
(power)
36
Ruby
Description
Example
==
(a == b) is not
true.
!=
(a != b) is true.
>
(a > b) is not
true.
<
(a < b) is true.
>=
(a >= b) is not
true.
<=
(a <= b) is
true.
<=>
(a <=> b)
returns -1.
===
(1...10) === 5
returns true.
.eql?
1 == 1.0
returns true,
but 1.eql?(1.0)
is false.
37
Ruby
equal?
if aObj is
duplicate of
bObj then aObj
== bObj is
true,
a.equal?bObj is
false but
a.equal?aObj is
true.
Description
Example
c = a + b will
assign the
value of a + b
into c
+=
c += a is
equivalent to c
=c+a
-=
c -= a is
equivalent to c
=c-a
*=
c *= a is
equivalent to c
=c*a
/=
c /= a is
equivalent to c
=c/a
%=
c %= a is
equivalent to c
=c%a
38
Ruby
**=
c **= a is
equivalent to c
= c ** a
39
Ruby
Description
Example
&
(a | b) will give
61, which is 0011
1101
(a ^ b) will give
49, which is 0011
0001
<<
>>
Description
and
Example
(a and b) is true.
40
Ruby
becomes true.
or
(a or b) is true.
&&
(a && b) is true.
||
(a || b) is true.
not
not(a
false.
&&
b)
is
Description
Conditional Expression
Example
If Condition is true ? Then value X
: Otherwise value Y
Ruby
In Ruby, these sequences are created using the ".." and "..." range operators.
The two-dot form creates an inclusive range, while the three-dot form creates a
range that excludes the specified high value.
Operator
Description
Example
..
...
1...10 Creates
from 1 to 9.
range
Usage 1
defined? variable # True if variable is initialized
For Example
foo = 42
defined? foo
# => "local-variable"
defined? $_
# => "global-variable"
defined? bar
Usage 2
defined? method_call # True if a method is defined
For Example
defined? puts
# => "method"
42
Ruby
defined? puts(bar)
defined? unpack
Usage 3
# True if a method exists that can be called with super user
defined? super
For Example
defined? super
defined? super
Usage 4
defined? yield
For Example
defined? yield
defined? yield
Ruby
module Foo
MR_COUNT = 0
::MR_COUNT = 1
MR_COUNT = 2
end
puts MR_COUNT
puts Foo::MR_COUNT
Second Example
CONST = ' out there'
class Inside_one
CONST = proc {' in there'}
def where_is_my_CONST
::CONST + ' inside one'
end
end
class Inside_two
CONST = ' inside two'
def where_is_my_CONST
CONST
end
end
puts Inside_one.new.where_is_my_CONST
puts Inside_two.new.where_is_my_CONST
puts Object::CONST + Inside_two::CONST
puts Inside_two::CONST + CONST
puts Inside_one::CONST
puts Inside_one::CONST.call + Inside_two::CONST
Operator
Description
44
Ruby
Yes
::
Yes
[ ] [ ]=
Yes
**
Yes
!~+-
Yes
*/%
Yes
+-
Yes
>> <<
Yes
&
Yes
^|
Yes
Yes
<=> == === != =~ !~
&&
Logical 'AND'
||
Logical 'OR'
.. ...
?:
= %= { /= -= += |=
&= >>= <<= *= &&=
||= **=
45
Ruby
defined?
not
or and
NOTE: Operators with a Yes in the method column are actually methods, and as
such may be overridden.
46
7. COMMENTS
Ruby
Comments are lines of annotation within Ruby code that are ignored at runtime.
A single line comment starts with # character and they extend from # to the
end of the line as follows:
#!/usr/bin/ruby -w
=begin
This is a multiline comment and con spwan as many lines as you
like. But =begin and =end should come in the first line only.
=end
When executed, the above program produces the following result:
Hello, Ruby!
47
Ruby
Make sure trailing comments are far enough from the code and that they are
easily distinguished. If more than one trailing comment exists in a block, align
them. For example:
@counter
@siteCounter
48
Ruby
Ruby offers conditional structures that are pretty common to modern languages.
Here, we will explain all the conditional statements and modifiers available in
Ruby.
Example
#!/usr/bin/ruby
x=1
if x > 2
puts "x is greater than 2"
elsif x <= 2 and x!=0
puts "x is 1"
else
puts "I can't guess the number"
49
Ruby
end
x is 1
Ruby if modifier
Syntax
code if condition
Executes code if the conditional is true.
Example
#!/usr/bin/ruby
$debug=1
print "debug\n" if $debug
This will produce the following result:
debug
50
Ruby
Example
#!/usr/bin/ruby
x=1
unless x>2
puts "x is less than 2"
else
puts "x is greater than 2"
end
This will produce the following result:
x is less than 2
Example
#!/usr/bin/ruby
$var =
$var = false
print "3 -- Value is set\n" unless $var
This will produce the following result:
1 -- Value is set
3 -- Value is set
51
Ruby
52
Ruby
end
Example
#!/usr/bin/ruby
$age =
case $age
when 0 .. 2
puts "baby"
when 3 .. 6
puts "little child"
when 7 .. 12
puts "child"
when 13 .. 18
puts "youth"
else
puts "adult"
end
This will produce the following result:
little child
53
9. LOOPS
Ruby
Loops in Ruby are used to execute the same block of code a specified number of
times. This chapter details all the loop statements supported by Ruby.
Example
#!/usr/bin/ruby
$i = 0
$num = 5
do
54
Ruby
OR
begin
code
end while conditional
Executes code while conditional is true.
If a while modifier follows a begin statement with no rescue or ensure clauses,
code is executed once before conditional is evaluated.
Example
#!/usr/bin/ruby
$i = 0
$num = 5
begin
puts("Inside the loop i = #$i" )
$i +=1
end while $i < $num
This will produce the following result:
Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
55
Ruby
Example
#!/usr/bin/ruby
$i = 0
$num = 5
do
OR
56
Ruby
begin
code
end until conditional
Executes code while conditional is false.
If an until modifier follows a begin statement with no rescue or ensure clauses,
code is executed once before conditional is evaluated.
Example
#!/usr/bin/ruby
$i = 0
$num = 5
begin
puts("Inside the loop i = #$i" )
$i +=1;
end until $i > $num
This will produce the following result:
Inside the loop i = 0
Inside the loop i = 1
Inside the loop i = 2
Inside the loop i = 3
Inside the loop i = 4
Inside the loop i = 5
Ruby
Example
#!/usr/bin/ruby
for i in 0..5
puts "Value of local variable is #{i}"
end
Here, we have defined the range 0..5. The statement for i in 0..5 will allow i to
take values in the range from 0 to 5 (including 5). This will produce the following
result:
Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5
A for...in loop is almost exactly equivalent to the following:
(expression).each do |variable[, variable...]| code end
except that a for loop doesn't create a new scope for the local variables. A for
loop's expression is separated from code by the reserved word do, a newline, or
a semicolon.
Example
#!/usr/bin/ruby
(0..5).each do |i|
puts "Value of local variable is #{i}"
end
This will produce the following result:
Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
Value of local variable is 3
58
Ruby
Example
#!/usr/bin/ruby
for i in 0..5
if i > 2 then
break
end
puts "Value of local variable is #{i}"
end
This will produce the following result:
Value of local variable is 0
Value of local variable is 1
Value of local variable is 2
59
Ruby
Example
#!/usr/bin/ruby
for i in 0..5
if i < 2 then
next
end
puts "Value of local variable is #{i}"
end
This will produce the following result:
Value of local variable is 2
Value of local variable is 3
Value of local variable is 4
Value of local variable is 5
Example
#!/usr/bin/ruby
for i in 0..5
if i < 2 then
puts "Value of local variable is #{i}"
redo
end
end
60
Ruby
This will produce the following result and will go in an infinite loop:
Value of local variable is 0
Value of local variable is 0
............................
end
If retry appears in the iterator, the block, or the body of the for expression,
restarts the invocation of the iterator call. Arguments to the iterator is reevaluated.
for i in 1..5
retry if some_condition # restart from i == 1
end
Example
#!/usr/bin/ruby
for i in 1..5
retry if
i > 2
61
Ruby
This will produce the following result and will go in an infinite loop:
Value of local variable is 1
Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
Value of local variable is 1
Value of local variable is 2
............................
62
10. METHODS
Ruby
Ruby methods are very similar to functions in any other programming language.
Ruby methods are used to bundle one or more repeatable statements into a
single unit.
Method names should begin with a lowercase letter. If you begin a method name
with an uppercase letter, Ruby might think that it is a constant and hence can
parse the call incorrectly.
Methods should be defined before calling them, otherwise Ruby will raise an
exception for undefined method invoking.
Syntax
def method_name [( [arg [= default]]...[, * arg [, &expr ]])]
expr..
end
So, you can define a simple method as follows:
def method_name
expr..
end
You can represent a method that accepts parameters like this:
def method_name (var1, var2)
expr..
end
You can set default values for the parameters, which will be used if method is
called without passing the required parameters:
def method_name (var1=value1, var2=value2)
expr..
end
63
Ruby
Whenever you call the simple method, you write only the method name as
follows:
method_name
However, when you call a method with parameters, you write the method name
along with the parameters, such as:
method_name 25, 30
The most important drawback to using methods with parameters is that you
need to remember the number of parameters whenever you call such methods.
For example, if a method accepts three parameters and you pass only two, then
Ruby displays an error.
Example
#!/usr/bin/ruby
Ruby
k = 0
end
This method, when called, will return the last declared variable k.
Syntax
return [expr[`,' expr...]]
If more than two expressions are given, the array containing these values will be
the return value. If no expression given, nil will be the return value.
Example
return
OR
return 12
OR
return 1,2,3
Have a look at this example:
#!/usr/bin/ruby
def test
i = 100
j = 200
k = 300
return i, j, k
end
65
Ruby
var = test
puts var
This will produce the following result:
100
200
300
Ruby
Class Methods
When a method is defined outside of the class definition, the method is marked
as private by default. On the other hand, the methods defined in the class
definition are marked as public by default. The default visibility and the private
mark of the methods can be changed by public or private of the Module.
Whenever you want to access a method of a class, you first need to instantiate
the class. Then, using the object, you can access any member of the class.
Ruby gives you a way to access a method without instantiating a class. Let us
see how a class method is declared and accessed:
class Accounts
def reading_charge
end
def Accounts.return_date
end
end
See how the method return_date is declared. It is declared with the class name
followed by a period, which is followed by the name of the method. You can
access this class method directly as follows:
Accounts.return_date
To access this method, you need not create objects of the class Accounts.
67
Ruby
Syntax
alias method-name method-name
alias global-variable-name global-variable-name
Example
alias foo bar
alias $MATCH $&
Here, we have defined foo alias for bar, and $MATCH is an alias for $&
Syntax
undef method-name
Example
To undefine a method called bar, do the following:
undef bar
68
11. BLOCKS
Ruby
You have seen how Ruby defines methods where you can put number of
statements and then you call that method. Similarly, Ruby has a concept of
Block.
A block is always invoked from a function with the same name as that of
the block. This means that if you have a block with the name test, then
you use the function test to invoke this block.
Syntax
block_name{
statement1
statement2
..........
}
Here, you will learn to invoke a block by using a simple yield statement. You will
also learn to use a yield statement with parameters for invoking a block. You will
check the sample code with both types of yield statements.
def test
puts "You are in the method"
yield
puts "You are again back to the method"
yield
69
Ruby
end
test {puts "You are in the block"}
This will produce the following result:
You are in the method
You are in the block
You are again back to the method
You are in the block
You also can pass parameters with the yield statement. Here is an example:
#!/usr/bin/ruby
def test
yield 5
puts "You are in the method test"
yield 100
end
test {|i| puts "You are in the block #{i}"}
This will produce the following result:
You are in the block 5
You are in the method test
You are in the block 100
Here, the yield statement is written followed by parameters. You can even pass
more than one parameter. In the block, you place a variable between two
vertical lines (||) to accept the parameters. Therefore, in the preceding code,
the yield 5 statement passes the value 5 as a parameter to the test block.
Now, look at the following statement:
test {|i| puts "You are in the block #{i}"}
Here, the value 5 is received in the variable i. Now, observe the following puts
statement:
puts "You are in the block #{i}"
70
Ruby
def test
yield
end
test{ puts "Hello world"}
This example is the simplest way to implement a block. You call the test block by
using the yield statement.
But if the last argument of a method is preceded by &, then you can pass a
block to this method and this block will be assigned to the last parameter. In
case both * and & are present in the argument list, & should come later.
#!/usr/bin/ruby
def test(&block)
block.call
end
test { puts "Hello World!"}
71
Ruby
BEGIN {
# BEGIN block code
puts "BEGIN code block"
}
END {
# END block code
puts "END code block"
}
# MAIN block code
puts "MAIN code block"
A program may include multiple BEGIN and END blocks. BEGIN blocks are
executed in the order they are encountered. END blocks are executed in reverse
order. When executed, the above program produces the following result:
BEGIN code block
MAIN code block
END code block
72
Ruby
Syntax
module Identifier
statement1
statement2
...........
end
Module constants are named just like class constants, with an initial uppercase
letter. The method definitions look similar, too: Module methods are defined just
like class methods.
As with class methods, you call a module method by preceding its name with the
module's name and a period, and you reference a constant using the module
name and two colons.
Example
#!/usr/bin/ruby
module Trig
PI = 3.141592654
def Trig.sin(x)
# ..
end
73
Ruby
def Trig.cos(x)
# ..
end
end
We can define one more module with the same function name but different
functionality:
#!/usr/bin/ruby
module Moral
VERY_BAD = 0
BAD = 1
def Moral.sin(badness)
# ...
end
end
Like class methods, whenever you define a method in a module, you specify the
module name followed by a dot and then the method name.
Syntax
require filename
Here, it is not required to give .rb extension along with a file name.
Example:
$LOAD_PATH << '.'
require 'trig.rb'
74
Ruby
require 'moral'
y = Trig.sin(Trig::PI/4)
wrongdoing = Moral.sin(Moral::VERY_BAD)
Here we are using $LOAD_PATH << '.' to make Ruby aware that included files
must be searched in the current directory. If you do not want to use
$LOAD_PATH then you can use require_relative to include files from a relative
directory.
IMPORTANT: Here, both the files contain the same function name. So, this will
result in code ambiguity while including in calling program but modules avoid
this code ambiguity and we are able to call appropriate function using module
name.
Syntax
include modulename
If a module is defined in a separate file, then it is required to include that file
using require statement before embedding module in a class.
Example
Consider the following module written in support.rb file.
module Week
FIRST_DAY = "Sunday"
def Week.weeks_in_month
puts "You have four weeks in a month"
end
def Week.weeks_in_year
puts "You have 52 weeks in a year"
end
end
75
Ruby
class Decade
include Week
no_of_yrs=10
def no_of_months
puts Week::FIRST_DAY
number=10*12
puts number
end
end
d1=Decade.new
puts Week::FIRST_DAY
Week.weeks_in_month
Week.weeks_in_year
d1.no_of_months
This will produce the following result:
Sunday
You have four weeks in a month
You have 52 weeks in a year
Sunday
120
Mixins in Ruby
Before going through this section, we assume you have the knowledge of Object
Oriented Concepts.
When a class can inherit features from more than one parent class, the class is
supposed to show multiple inheritance.
76
Ruby
Ruby does not support multiple inheritance directly but Ruby Modules have
another wonderful use. At a stroke, they pretty much eliminate the need for
multiple inheritance, providing a facility called a mixin.
Mixins give you a wonderfully controlled way of adding functionality to classes.
However, their true power comes out when the code in the mixin starts to
interact with code in the class that uses it.
Let us examine the following sample code to gain an understand of mixin:
module A
def a1
end
def a2
end
end
module B
def b1
end
def b2
end
end
class Sample
include A
include B
def s1
end
end
samp=Sample.new
samp.a1
samp.a2
samp.b1
samp.b2
samp.s1
77
Ruby
Module A consists of the methods a1 and a2. Module B consists of the methods
b1 and b2. The class Sample includes both modules A and B. The class Sample
can access all four methods, namely, a1, a2, b1, and b2. Therefore, you can see
that the class Sample inherits from both the modules. Thus, you can say the
class Sample shows multiple inheritance or a mixin.
78
13. STRINGS
Ruby
Expression Substitution
Expression substitution is a means of embedding the value of any Ruby
expression into a string using #{ and }:
#!/usr/bin/ruby
x, y, z = 12, 36, 72
puts "The value of x is #{ x }."
puts "The sum of x and y is #{ x + y }."
puts "The average was #{ (x + y + z)/3 }."
This will produce the following result:
The value of x is 12.
The sum of x and y is 48.
The average was 40.
79
Ruby
Escape Characters
Following table is a list of escape or non-printable characters that can be
represented with the backslash notation.
NOTE: In a double-quoted string, an escape character is interpreted; in a singlequoted string, an escape character is preserved.
Backslash
notation
Description
Hexadecimal
character
\a
0x07
Bell or alert
\b
0x08
Backspace
\cx
Control-x
\C-x
Control-x
\e
0x1b
Escape
\f
0x0c
Formfeed
\M-\C-x
\n
\nnn
Meta-Control-x
0x0a
Newline
Octal notation, where n is in the range 0.7
80
Ruby
\r
0x0d
Carriage return
\s
0x20
Space
\t
0x09
Tab
\v
0x0b
Vertical tab
\x
Character x
\xnn
Character Encoding
The default character set for Ruby is ASCII, whose characters may be
represented by single bytes. If you use UTF-8, or another modern character set,
characters may be represented in one to four bytes.
You can change your character set using $KCODE at the beginning of your
program, like this:
$KCODE = 'u'
Following are the possible values for $KCODE.
Code
Description
EUC.
UTF-8.
Ruby
new [String.new(str="")]
This will return a new string object containing a copy of str. Now, using str
object, we can all use any available instance methods. For example:
#!/usr/bin/ruby
puts "#{foo}"
This will produce the following result:
this is test
Following are the public String methods ( Assuming str is a String object ):
SN
1
str * integer
Returns a new string containing integer times str. In other words, str is
repeated integer imes.
str + other_str
Concatenates other_str to str.
Ruby
str == obj
Tests str and obj for equality. If obj is not a String, returns false; returns
true if str <=> obj returns 0.
str =~ obj
Matches str against a regular expression pattern obj. Returns the position
where the match starts; otherwise, false.
str =~ obj
Matches str against a regular expression pattern obj. Returns the position
where the match starts; otherwise, false.
str.capitalize
Capitalizes a string.
10
str.capitalize!
Same as capitalize, but changes are made in place.
11
str.casecmp
Makes a case-insensitive comparison of strings.
12
str.center
Centers a string.
13
str.chomp
Removes the record separator ($/), usually \n, from the end of a string.
If no record separator exists, does nothing.
14
str.chomp!
Same as chomp, but changes are made in place.
15
str.chop
Removes the last character in str.
83
Ruby
16
str.chop!
Same as chop, but changes are made in place.
17
str.concat(other_str)
Concatenates other_str to str.
18
str.count(str, ...)
Counts one or more sets of characters. If there is more than one set of
characters, counts the intersection of those sets
19
str.crypt(other_str)
Applies a one-way cryptographic hash to str. The argument is the salt
string, which should be two characters long, each character in the range
a.z, A.Z, 0.9, . or /.
20
str.delete(other_str, ...)
Returns a copy of str with all characters in the intersection of its
arguments deleted.
21
str.delete!(other_str, ...)
Same as delete, but changes are made in place.
22
str.downcase
Returns a copy of str with all uppercase letters replaced with lowercase.
23
str.downcase!
Same as downcase, but changes are made in place.
24
str.dump
Returns a version of str with all nonprinting characters replaced by \nnn
notation and all special characters escaped.
25
Ruby
26
27
28
str.empty?
Returns true if str is empty (has a zero length).
29
str.eql?(other)
Two strings are equal if they have the same length and content.
30
31
[or]
33
Ruby
block }
Performs the substitutions of String#gsub in place, returning str, or nil if
no substitutions were performed.
34
str.hash
Returns a hash based on the string's length and content.
35
str.hex
Treats leading characters from str as a string of hexadecimal digits (with
an optional sign and an optional 0x) and returns the corresponding
number. Zero is returned on error.
36
37
38
str.insert(index, other_str)
Inserts other_str before the character at the given index, modifying str.
Negative indices count from the end of the string, and insert after the
given character. The intent is to insert a string so that it starts at the
given index.
39
str.inspect
Returns a printable version of str, with special characters escaped.
40
41
str.length
86
Ruby
43
str.lstrip
Returns a copy of str with leading whitespace removed.
44
str.lstrip!
Removes leading whitespace from str, returning nil if no change was
made.
45
str.match(pattern)
Converts pattern to a Regexp (if it isn't already one), then invokes its
match method on str.
46
str.oct
Treats leading characters of str as a string of octal digits (with an optional
sign) and returns the corresponding number. Returns 0 if the conversion
fails.
47
str.replace(other_str)
Replaces the contents and taintedness of str with the corresponding
values in other_str.
48
str.reverse
Returns a new string with the characters from str in reverse order.
49
str.reverse!
Reverses str in place.
50
87
Ruby
str.rindex(regexp [, fixnum])
Returns the index of the last occurrence of the given substring, character
(fixnum), or pattern (regexp) in str. Returns nil if not found. If the
second parameter is present, it specifies the position in the string to end
the search.characters beyond this point won't be considered.
51
52
str.rstrip
Returns a copy of str with trailing whitespace removed.
53
str.rstrip!
Removes trailing whitespace from str, returning nil if no change was
made.
54
str.scan(pattern) [or]
str.scan(pattern) { |match, ...| block }
Both forms iterate through str, matching the pattern (which may be a
Regexp or a String). For each match, a result is generated and either
added to the result array or passed to the block. If the pattern contains
no groups, each individual result consists of the matched string, $&. If
the pattern contains groups, each individual result is itself an array
containing one entry per group.
55
Ruby
of range; the Range form will raise a RangeError, and the Regexp and
String forms will silently ignore the assignment.
56
str.split(pattern=$;, [limit])
Divides str into substrings based on a delimiter, returning an array of
these substrings.
If pattern is a String, then its contents are used as the delimiter when
splitting str. If pattern is a single space, str is split on whitespace, with
leading whitespace and runs of contiguous whitespace characters
ignored.
If pattern is a Regexp, str is divided where the pattern matches.
Whenever the pattern matches a zero-length string, str is split into
individual characters.
If pattern is omitted, the value of $; is used. If $; is nil (which is the
default), str is split on whitespace as if ` ` were specified.
If the limit parameter is omitted, trailing null fields are suppressed. If
limit is a positive number, at most that number of fields will be returned
(if limit is 1, the entire string is returned as the only entry in an array). If
negative, there is no limit to the number of fields returned, and trailing
null fields are not suppressed.
57
str.squeeze([other_str]*)
Builds a set of characters from the other_str parameter(s) using the
procedure described for String#count. Returns a new string where runs
of the same character that occur in this set are replaced by a single
character. If no arguments are given, all runs of identical characters are
replaced by a single character.
58
str.squeeze!([other_str]*)
Squeezes str in place, returning either str, or nil if no changes were
made.
59
str.strip
Returns a copy of str with leading and trailing whitespace removed.
60
str.strip!
Removes leading and trailing whitespace from str. Returns nil if str was
89
Ruby
not altered.
61
62
63
64
65
str.sum(n=16)
Returns a basic n-bit checksum of the characters in str, where n is the
optional Fixnum parameter, defaulting to 16. The result is simply the sum
of the binary value of each character in str modulo 2n - 1. This is not a
particularly good checksum.
66
str.swapcase
Returns a copy of str with uppercase alphabetic characters converted to
lowercase and lowercase characters converted to uppercase.
67
str.swapcase!
Equivalent to String#swapcase, but modifies the receiver in place,
returning str, or nil if no changes were made.
68
str.to_f
>Returns the result of interpreting leading characters in str as a floating90
Ruby
point number. Extraneous characters past the end of a valid number are
ignored. If there is not a valid number at the start of str, 0.0 is returned.
This method never raises an exception.
69
str.to_i(base=10)
Returns the result of interpreting leading characters in str as an integer
base (base 2, 8, 10, or 16). Extraneous characters past the end of a valid
number are ignored. If there is not a valid number at the start of str, 0 is
returned. This method never raises an exception.
70
71
str.tr(from_str, to_str)
Returns a copy of str with the characters in from_str replaced by the
corresponding characters in to_str. If to_str is shorter than from_str, it is
padded with its last character. Both strings may use the c1.c2 notation to
denote ranges of characters, and from_str may start with a ^, which
denotes all characters except those listed.
72
str.tr!(from_str, to_str)
Translates str in place, using the same rules as String#tr. Returns str, or
nil if no changes were made.
73
str.tr_s(from_str, to_str)
Processes a copy of str as described under String#tr, then removes
duplicate characters in regions that were affected by the translation.
74
str.tr_s!(from_str, to_str)
Performs String#tr_s processing on str in place, returning str, or nil if no
changes were made.
75
str.unpack(format)
>Decodes str (which may contain binary data) according to the format
string, returning an array of each value extracted. The format string
consists of a sequence of single-character directives, summarized in
Table 18. Each directive may be followed by a number, indicating the
number of times to repeat with this directive. An asterisk (*) will use up
91
Ruby
str.upcase
Returns a copy of str with all lowercase letters replaced with their
uppercase counterparts. The operation is locale insensitive. Only
characters a to z are affected.
77
str.upcase!
Changes the contents of str to uppercase, returning nil if no changes are
made.
78
Returns
Description
String
String
String.
String
String
Fixnum
Fixnum
Ruby
D, d
Float
Treats sizeof(double)
double.
Float
Float
F, f
Float
Float
String
Treats sizeof(float)
network byte order.
String
String
Integer
Integer
Integer
Integer
String
Quoted-printable.
String
Base64-encoded.
characters
characters
as
as
as
native
float
float
in
in
successive
93
Ruby
Integer
Fixnum
String
String
Integer
Integer
Fixnum
Fixnum
Integer
String
Fixnum
Fixnum
Integer
BER-compressed integer.
UU-encoded.
Ruby
x
Z
Example
Try the following example to unpack various data.
"abc \0\0abc \0\0".unpack('A6Z6')
"abc \0\0".unpack('a3a3')
"aa".unpack('b8B8')
"aaa".unpack('h2H2c')
"\xfe\xff\xfe\xff".unpack('sS')
"now=20is".unpack('M*')
"whole".unpack('xax2aX2aX1aX2a')
95
14. ARRAYS
Ruby
Ruby arrays are ordered, integer-indexed collections of any object. Each element
in an array is associated with and referred to by an index.
Array indexing starts at 0, as in C or Java. A negative index is assumed relative
to the end of the array --- that is, an index of -1 indicates the last element of
the array, -2 is the next to last element in the array, and so on.
Ruby arrays can hold objects such as String, Integer, Fixnum, Hash, Symbol,
even other Array objects. Ruby arrays are not as rigid as arrays in other
languages. Ruby arrays grow automatically while adding elements to them.
Creating Arrays
There are many ways to create or initialize an array. One way is with the new
class method:
names = Array.new
You can set the size of an array at the time of creating array:
names = Array.new(20)
The array names now has a size or length of 20 elements. You can return the
size of an array with either the size or length methods:
#!/usr/bin/ruby
names = Array.new(20)
puts names.size
# This returns 20
96
Ruby
puts "#{names}"
This will produce the following result:
macmacmacmac
You can also use a block with new, populating each element with what the block
evaluates to:
#!/usr/bin/ruby
puts "#{nums}"
This will produce the following result:
024681012141618
There is another method of Array, []. It works like this:
nums = Array.[](1, 2, 3, 4,5)
One more form of array creation is as follows:
nums = Array[1, 2, 3, 4,5]
The Kernel module available in core Ruby has an Array method, which only
accepts a single argument. Here, the method takes a range as an argument to
create an array of digits:
#!/usr/bin/ruby
digits = Array(0..9)
puts "#{digits}"
97
Ruby
digits = Array(0..9)
num = digits.at(6)
puts "#{num}"
This will produce the following result:
6
Following are the public array methods (assuming array is an array object):
SN
1
array + other_array
Returns a new array built by concatenating the two arrays together to
98
Ruby
array - other_array
Returns a new array that is a copy of the original array, removing any
items that also appear in other_array.
array | other_array
Returns a new array by joining array with other_array, removing
duplicates.
array == other_array
Two arrays are equal if they contain the same number of elements and if
each element is equal to (according to Object.==) the corresponding
element in the other array.
10
11
Ruby
array.abbrev(pattern = nil)
Calculates the set of unambiguous abbreviations for the strings in self. If
passed a pattern or a string, only the strings matching the pattern or
starting with the string are considered.
13
array.assoc(obj)
Searches through an array whose elements are also arrays comparing obj
with the first element of each contained array using obj.==. Returns the
first contained array that matches or nil if no match is found.
14
array.at(index)
Returns the element at index. A negative index counts from the end of
self. Returns nil if the index is out of range.
15
array.clear
Removes all elements from array.
16
17
100
Ruby
18
array.compact
Returns a copy of self with all nil elements removed.
19
array.compact!
Removes nil elements from array. Returns nil if no changes were made.
20
array.concat(other_array)
Appends the elements in other_array to self.
21
array.delete(obj) [or]
array.delete(obj) { block }
Deletes items from self that are equal to obj. If the item is not found,
returns nil. If the optional code block is given, returns the result of block if
the item is not found.
22
array.delete_at(index)
Deletes the element at the specified index, returning that element, or nil if
the index is out of range.
23
24
25
26
array.empty?
Returns true if the self array contains no elements.
27
array.eql?(other)
Returns true if array and other are the same object, or are both arrays
101
Ruby
array.fetch(index) [or]
array.fetch(index, default) [or]
array.fetch(index) { |index| block }
Tries to return the element at position index. If index lies outside the
array, the first form throws an IndexError exception, the second form
returns default, and the third form returns the value of invoking block,
passing in index. Negative values of index count from the end of the
array.
29
array.fill(obj) [or]
array.fill(obj, start [, length]) [or]
array.fill(obj, range) [or]
array.fill { |index| block } [or]
array.fill(start [, length] ) { |index| block } [or]
array.fill(range) { |index| block }
The first three forms set the selected elements of self to obj. A start of nil
is equivalent to zero. A length of nil is equivalent to self.length. The last
three forms fill the array with the value of the block. The block is passed
with the absolute index of each element to be filled.
30
array.first [or]
array.first(n)
Returns the first element, or the first n elements, of the array. If the
array is empty, the first form returns nil, and the second form returns an
empty array.
31
array.flatten
Returns a new array that is a one-dimensional flattening of this array
(recursively).
32
array.flatten!
Flattens array in place. Returns nil if no modifications were made. (array
contains no subarrays.)
102
Ruby
33
array.frozen?
Returns true if array is frozen (or temporarily frozen while being sorted).
34
array.hash
Computes a hash-code for array. Two arrays with the same content will
have the same hash code.
35
array.include?(obj)
Returns true if obj is present in self, false otherwise.
36
array.index(obj)
Returns the index of the first object in self that is == to obj. Returns nil if
no match is found.
37
38
39
array.insert(index, obj...)
Inserts the given values before the element with the given index (which
may be negative).
40
array.inspect
Creates a printable version of array.
41
array.join(sep=$,)
Returns a string created by converting each element of the array to a
string, separated by sep.
103
Ruby
42
43
array.length
Returns the number of elements in self. May be zero.
44
45
46
array.nitems
Returns the number of non-nil elements in self. May be zero.
47
array.pack(aTemplateString)
Packs the contents of array into a binary sequence according to the
directives in a TemplateString. Directives A, a, and Z may be followed by
a count, which gives the width of the resulting field. The remaining
directives also may take a count, indicating the number of array elements
to convert. If the count is an asterisk (*), all remaining array elements
will be converted. Any of the directives is still may be followed by an
underscore (_) to use the underlying platform's native size for the
specified type; otherwise, they use a platform independent size. Spaces
are ignored in the template string.
48
array.pop
Removes the last element from array and returns it, or nil if array is
empty.
49
array.push(obj, ...)
Pushes (appends) the given obj onto the end of this array. This
104
Ruby
array.rassoc(key)
Searches through the array whose elements are also arrays. Compares
key with the second element of each contained array using ==. Returns
the first contained array that matches.
51
52
53
array.replace(other_array)
Replaces the contents of array with the contents of other_array,
truncating or expanding if necessary.
54
array.reverse
Returns a new array containing array's elements in reverse order.
55
array.reverse!
Reverses array in place.
56
57
array.rindex(obj)
Returns the index of the last object in array == to obj. Returns nil if no
match is found.
58
Ruby
value.
59
array.shift
Returns the first element of self and removes it (shifting all other
elements down by one). Returns nil if the array is empty.
60
array.size
Returns the length of array (number of elements). Alias for length.
61
62
63
64
65
array.to_a
Returns self. If called on a subclass of Array, converts the receiver to an
Array object.
66
array.to_ary
Returns self.
106
Ruby
67
array.to_s
Returns self.join.
68
array.transpose
Assumes that self is an array of arrays and transposes the rows and
columns.
69
array.uniq
Returns a new array by removing duplicate values in array.
70
array.uniq!
Removes duplicate elements from self. Returns nil if no changes are made
(that is, no duplicates are found).
71
array.unshift(obj, ...)
Prepends objects to the front of array, other elements up one.
72
array.values_at(selector,...)
Returns an array containing the elements in self corresponding to the
given selector (one or more). The selectors may be either integer indices
or ranges.
73
Description
Moves to absolute position.
107
Ruby
Unsigned char.
Char.
D, d
F, f
Unsigned integer.
Integer.
Unsigned long.
Long.
Ruby
Base64-encoded string.
Q, q
64-bit number.
Unsigned short.
Short.
UTF-8.
UU-encoded string.
Back up a byte.
Null byte.
Example
Try the following example to pack various data.
a = [ "a", "b", "c" ]
n = [ 65, 66, 67 ]
109
Ruby
puts a.pack("A3A3A3")
#=> "a
"
puts a.pack("a3a3a3")
#=> "a\000\000b\000\000c\000\000"
puts n.pack("ccc")
#=> "ABC"
abc
ABC
110
15. HASHES
Ruby
Creating Hashes
As with arrays, there is a variety of ways to create hashes. You can create an
empty hash with the new class method:
months = Hash.new
You can also use new to create a hash with a default value, which is otherwise
just nil:
months = Hash.new( "month" )
or
puts "#{months[0]}"
puts "#{months[72]}"
This will produce the following result:
month
month
111
Ruby
#!/usr/bin/ruby
puts "#{H['a']}"
puts "#{H['b']}"
This will produce the following result:
100
200
You can use any Ruby object as a key or value, even an array, so the following
example is a valid one:
[1,"jan"] => "January"
$, = ", "
months = Hash.new( "month" )
keys = months.keys
112
Ruby
puts "#{keys}"
This will produce the following result:
["1", "2"]
Following are the public hash methods (assuming hash is an array object):
SN
Tests whether two hashes are equal, based on whether they have the
same number of key-value pairs, and whether the key-value pairs match
the corresponding pair in each hash.
hash.[key]
Using a key, references a value from hash. If the key is not found, returns
a default value.
hash.[key]=value
Associates the value given by value with the key given by key.
hash.clear
Removes all key-value pairs from hash.
hash.default(key = nil)
Returns the default value for hash, nil if not set by default=. ([] returns a
default value if the key does not exist in hash.)
hash.default = obj
Sets a default value for hash.
hash.default_proc
Returns a block if hash was created by a block.
hash.delete(key) [or]
Ruby
Deletes a key-value pair from hash for every pair the block evaluates to
true.
hash.each { |key,value| block }
10 Iterates over hash, calling the block once for each key, passing the keyvalue as a two-element array.
hash.each_key { |key| block }
11 Iterates over hash, calling the block once for each key, passing key as a
parameter.
hash.each_key { |key_value_array| block }
12 Iterates over hash, calling the block once for each key, passing the key and
value as parameters.
hash.each_key { |value| block }
13 Iterates over hash, calling the block once for each key, passing value as a
parameter.
hash.empty?
14 Tests whether hash is empty (contains no key-value pairs), returning true
or false.
hash.fetch(key [, default] ) [or]
hash.fetch(key) { | key | block }
15
Returns a value from hash for the given key. If the key can't be found, and
there are no other arguments, it raises an IndexError exception; if default is
given, it is returned; if the optional block is specified, its result is returned.
hash.has_key?(key) [or] hash.include?(key) [or]
17
hash.has_value?(value)
Tests whether hash contains the given value.
114
Ruby
hash.index(value)
18 Returns the key for the given value in hash, nil if no matching value is
found.
hash.indexes(keys)
19 Returns a new array consisting of values for the given key(s). Will insert
the default value for keys that are not found. This method is deprecated.
Use select.
hash.indices(keys)
20 Returns a new array consisting of values for the given key(s). Will insert
the default value for keys that are not found. This method is deprecated.
Use select.
21
hash.inspect
Returns a pretty print string version of hash.
hash.invert
22 Creates a new hash, inverting keys and values from hash; that is, in the
new hash, the keys from hash become values and values become keys.
23
24
hash.keys
Creates a new array with keys from hash.
hash.length
Returns the size or length of hash as an integer.
hash.merge(other_hash) [or]
25
hash.rehash
Rebuilds hash based on the current values for each key. If values have
115
Ruby
28
29
30
31 Returns a new array consisting of key-value pairs from hash for which the
blockreturns true.
32
33
hash.shift
Removes a key-value pair from hash, returning it as a two-element array.
hash.size
Returns the size or length of hash as an integer.
hash.sort
35
hash.store(key, value)
Stores a key-value pair in hash.
hash.to_a
37
38
hash.to_hash
Returns hash (self).
hash.to_s
Converts hash to an array, then converts that array to a string.
116
Ruby
hash.update(other_hash) [or]
39
40
41
hash.value?(value)
Tests whether hash contains the given value.
hash.values
Returns a new array containing all the values of hash.
hash.values_at(obj, ...)
42 Returns a new array containing the values from hash that are associated
with the given key or keys.
117
Ruby
The Time class represents dates and times in Ruby. It is a thin layer over the
system date and time functionality provided by the operating system. This class
may be unable on your system to represent dates before 1970 or after 2038.
This chapter makes you familiar with all the most wanted concepts of date and
time.
time1 = Time.new
# Time.now is a synonym:
time2 = Time.now
puts "Current Time : " + time2.inspect
This will produce the following result:
Current Time : Mon Jun 02 12:02:39 -0700 2008
Current Time : Mon Jun 02 12:02:39 -0700 2008
time = Time.new
# Components of a Time
118
Ruby
puts time.month
puts time.day
puts time.wday
puts time.yday
puts time.hour
puts time.min
# => 59
puts time.sec
# => 59
puts time.usec
puts time.zone
Ruby
Time.utc(2008, 7, 8, 9, 10)
# July 8, 2008, 09:10:11 GMT (same as UTC)
Time.gm(2008, 7, 8, 9, 10, 11)
Following is the example to get all the components in an array in the following
format:
[sec,min,hour,day,month,year,wday,yday,isdst,zone]
Try the following:
#!/usr/bin/ruby -w
time = Time.new
values = time.to_a
p values
This will generate the following result:
[26, 10, 12, 2, 6, 2008, 1, 154, false, "MST"]
This array could be passed to Time.utc or Time.local functions to get different
format of dates as follows:
#!/usr/bin/ruby -w
time = Time.new
values = time.to_a
puts Time.utc(*values)
This will generate the following result:
Mon Jun 02 12:15:36 UTC 2008
Following is the way to get time represented internally as seconds since the
(platform-dependent) epoch:
# Returns number of seconds since epoch
time = Time.now.to_i
120
Ruby
time.isdst
time.utc?
time.localtime
time.gmtime
time.getlocal
time.getutc
puts time.to_s
puts time.ctime
puts time.localtime
121
Ruby
2 12:35:19 2008
Description
%a
%A
%b
%B
%c
%d
%H
%I
%j
%m
%M
%p
Ruby
%S
%U
Week number of the current year, starting with the first Sunday as
the first day of the first week (00 to 53).
%W
Week number of the current year, starting with the first Monday as
the first day of the first week (00 to 53).
%w
%x
%X
%y
%Y
%Z
%%
Literal % character.
Time Arithmetic
You can perform simple arithmetic with time as follows:
now = Time.now
# Current time
puts now
past = now - 10
puts past
future = now + 10
puts future
# => 10
Ruby
puts diff
This will produce the following result:
Thu Aug 01 20:57:05 -0700 2013
Thu Aug 01 20:56:55 -0700 2013
Thu Aug 01 20:57:15 -0700 2013
10.0
124
17. RANGES
Ruby
Ranges as Sequences
Ranges as Conditions
Ranges as Intervals
Ranges as Sequences
The first and perhaps the most natural use of ranges is to express a sequence.
Sequences have a start point, an end point, and a way to produce successive
values in the sequence.
Ruby creates these sequences using the ''..'' and ''...'' range operators. The twodot form creates an inclusive range, while the three-dot form creates a range
that excludes the specified high value.
(1..5)
#==> 1, 2, 3, 4, 5
(1...5)
#==> 1, 2, 3, 4
('a'..'d')
$, =", "
range1 = (1..10).to_a
range2 = ('bar'..'bat').to_a
puts "#{range1}"
puts "#{range2}"
125
Ruby
# Assume a range
digits = 0..9
puts digits.include?(5)
ret = digits.min
puts "Min value is #{ret}"
ret = digits.max
puts "Max value is #{ret}"
digits.each do |digit|
puts "In Loop #{digit}"
end
This will produce the following result:
true
Min value is 0
Max value is 9
Rejected values are 5, 6, 7, 8, 9
In Loop 0
In Loop 1
In Loop 2
In Loop 3
126
Ruby
In Loop 4
In Loop 5
In Loop 6
In Loop 7
In Loop 8
In Loop 9
Ranges as Conditions
Ranges may also be used as conditional expressions. For example, the following
code fragment prints sets of lines from the standard input, where the first line in
each set contains the word start and the last line the word end.:
while gets
print if /start/../end/
end
Ranges can be used in case statements:
#!/usr/bin/ruby
score = 70
puts result
This will produce the following result:
Pass with Merit
127
Ruby
Ranges as Intervals
A final use of the versatile range is as an interval test: seeing if some value falls
within the interval represented by the range. This is done using ===, the case
equality operator.
#!/usr/bin/ruby
if ((1..10) === 5)
puts "5 lies in (1..10)"
end
128
18. ITERATORS
Ruby
Iterators are nothing but methods supported by collections. Objects that store a
group of data members are called collections. In Ruby, arrays and hashes can be
termed collections.
Iterators return all the elements of a collection, one after the other. We will be
discussing two iterators here, each and collect. Let's look at these in detail.
Syntax
collection.each do |variable|
code
end
Executes code for each element in collection. Here, collection could be an array or
a ruby hash.
Example
#!/usr/bin/ruby
ary = [1,2,3,4,5]
ary.each do |i|
puts i
end
This will produce the following result:
1
2
3
4
5
129
Ruby
You always associate the each iterator with a block. It returns each value of the
array, one by one, to the block. The value is stored in the variable i and then
displayed on the screen.
Syntax
collection = collection.collect
The collect method need not always be associated with a block. The collect
method returns the entire collection, regardless of whether it is an array or a
hash.
Example
#!/usr/bin/ruby
a = [1,2,3,4,5]
b = Array.new
b = a.collect
puts b
This will produce the following result:
1
2
3
4
5
NOTE: The collect method is not the right way to do copying between arrays.
There is another method called a clone, which should be used to copy one array
into another array.
You normally use the collect method when you want to do something with each
of the values to get the new array. For example, this code produces an array b
containing 10 times each value in a.
130
Ruby
#!/usr/bin/ruby
a = [1,2,3,4,5]
b = a.collect{|x| 10*x}
puts b
This will produce the following result:
10
20
30
40
50
131
Ruby
Example
#!/usr/bin/ruby
132
Ruby
Example
The following code shows you how to use the gets statement. This code will
prompt the user to enter a value, which will be stored in a variable val and
finally will be printed on STDOUT.
#!/usr/bin/ruby
Example
The output of the following code is just the character H:
#!/usr/bin/ruby
str="Hello Ruby!"
putc str
This will produce the following result:
H
133
Ruby
Example
#!/usr/bin/ruby
Syntax
aFile = File.new("filename", "mode")
# ... process the file
aFile.close
Ruby
Modes
Description
Read-only mode. The file pointer is placed at the beginning of the file.
This is the default mode.
r+
Read-write mode. The file pointer will be at the beginning of the file.
Write-only mode. Overwrites the file if the file exists. If the file does
not exist, creates a new file for writing.
w+
Read-write mode. Overwrites the existing file if the file exists. If the
file does not exist, creates a new file for reading and writing.
Write-only mode. The file pointer is at the end of the file if the file
exists. That is, the file is in the append mode. If the file does not
exist, it creates a new file for writing.
a+
Read and write mode. The file pointer is at the end of the file if the
file exists. The file opens in the append mode. If the file does not
exist, it creates a new file for reading and writing.
Ruby
#!/usr/bin/ruby
Ruby
aFile.syswrite("ABCDEF")
aFile.each_byte {|ch| putc ch; putc ?. }
else
puts "Unable to open file!"
end
Characters are passed one by one to the variable ch and then displayed on the
screen as follows:
s. .a. .s.i.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g.
.p.u.r.p.o.s.e...
.
.
arr = IO.readlines("input.txt")
puts arr[0]
puts arr[1]
In this code, the variable arr is an array. Each line of the file input.txt will be an
element in the array arr. Therefore, arr[0] will contain the first line, whereas
arr[1] will contain the second line of the file.
Ruby
Following is the table, which can help you to choose different mask for chmod
method:
138
Ruby
Mask
Description
0700
0400
r for owner
0200
w for owner
0100
x for owner
0070
0040
r for group
0020
w for group
0010
x for group
0007
0004
r for other
0002
w for other
0001
x for other
4000
2000
1000
139
Ruby
File Inquiries
The following command tests whether a file exists before opening it:
#!/usr/bin/ruby
# a directory
File::directory?( "/usr/local/bin" ) # => true
# a file
File::directory?( "file.rb" ) # => false
The following command finds whether the file is readable, writable or
executable:
#!/usr/bin/ruby
File.readable?( "test.txt" )
# => true
File.writable?( "test.txt" )
# => true
File.zero?( "test.txt" )
# => true
Ruby
#!/usr/bin/ruby
File.size?( "text.txt" )
# => 1002
File::ftype( "test.txt" )
# => file
The ftype method identifies the type of the file by returning one of the following:
file, directory, characterSpecial, blockSpecial, fifo, link, socket, or unknown.
The following command can be used to find when a file was created, modified, or
last accessed :
#!/usr/bin/ruby
Directories in Ruby
All files are contained within various directories, and Ruby has no problem
handling these too. Whereas the File class handles files, directories are handled
with the Dir class.
You can get a list of the files and directories within a specific directory using
Dir.entries:
141
Ruby
Creating a Directory
The Dir.mkdir can be used to create directories:
Dir.mkdir("mynewdir")
You can also set permissions on a new directory (not one that already exists)
with mkdir:
NOTE: The mask 755 sets permissions owner, group, world [anyone] to rwxr-xrx where r = read, w = write, and x = execute.
Dir.mkdir( "mynewdir", 755 )
Deleting a Directory
The Dir.delete can be used to delete a directory. The Dir.unlink and Dir.rmdir
performs exactly the same function and are provided for convenience.
Dir.delete("testdir")
142
Ruby
Built-in Functions
Here are the ruby built-in functions to process files and directories:
Class Methods
SN
143
Ruby
Returns the filename at the end of path. If suffix is specified, it's deleted
from the end of the filename.
e.g. File.basename("/home/users/bin/ruby.exe") #=> "ruby.exe"
File::blockdev?( path)
Returns true if path is a block device.
File::chardev?( path)
Returns true if path is a character device.
File::chmod( mode, path...)
Changes the permission mode of the specified files.
File::chown( owner, group, path...)
Changes the owner and group of the specified files.
File::ctime( path)
Returns the last node change time for path.
File::delete( path...)
File::unlink( path...)
Deletes the specified files.
10
11
12
File::directory?( path)
Returns true if path is a directory.
File::dirname( path)
Returns the directory portion of path, without the final filename.
File::executable?( path)
Returns true if path is executable.
File::executable_real?( path)
Returns true if path is executable with real user permissions.
13 File::exist?( path)
144
Ruby
14
15
16
File::grpowned?( path)
Returns true if path is owned by the user's group.
File::join( item...)
18
Ruby
20
File::mtime( path)
Returns the last modification time for path.
File::new( path[, mode="r"])
File::open( path[, mode="r"])
File::open( path[, mode="r"]) {|f| ...}
21 Opens a file. If a block is specified, the block is executed with the new file
passed as an argument. The file is closed automatically when the block
exits. These methods differ from Kernel.open in that even if path begins
with |, the following string isn't run as a command.
22
23
24
25
25
26
27
28
29
File::owned?( path)
Returns true if path is owned by the effective user.
File::pipe?( path)
Returns true if path is a pipe.
File::readable?( path)
Returns true if path is readable.
File::readable_real?( path)
Returns true if path is readable with real user permissions.
File::readlink( path)
Returns the file pointed to by path.
File::rename( old, new)
Changes the filename from old to new.
File::setgid?( path)
Returns true if path's set-group-id permission bit is set.
File::setuid?( path)
Returns true if path's set-user-id permission bit is set.
File::size( path)
Returns the file size of path.
146
Ruby
30
31
File::size?( path)
Returns the file size of path, or nil if it's 0.
File::socket?( path)
Returns true if path is a socket.
File::split( path)
33
34
35
36
37
38
of
path
split
into
File::stat( path)
Returns a File::Stat object with information on path.
File::sticky?( path)
Returns true if path's sticky bit is set.
File::symlink( old, new)
Creates a symbolic link to file old.
File::symlink?( path)
Returns true if path is a symbolic link.
File::truncate(path, len)
Truncates the specified file to len bytes.
File::unlink(path...)
Deletes a file given at the path.
File::umask([ mask])
40
41
Ruby
42
43
File::writable_real?( path)
Returns true if path is writable with real user permissions.
File::zero?( path)
Returns true if the file size of path is 0.
Instance Methods
Assuming f is an instance of File class:
SN
1
f.chmode( mode)
Changes the permission mode of f.
f.ctime
Returns the last inode change time for f.
f.flock( op)
Calls flock(2). op may be 0 or a logical or of the File class constants
LOCK_EX, LOCK_NB, LOCK_SH, and LOCK_UN.
f.lstat
Same as stat, except that it returns information on symbolic links
themselves, not the files they point to.
f.mtime
Returns the last modification time for f.
148
Ruby
f.path
Returns the pathname used to create f.
10
f.truncate( len)
Truncates f to len bytes.
Class Methods
SN
1
Dir::chdir( path)
Changes the current directory.
149
Ruby
Dir::chroot( path)
Changes the root directory (only allowed by super user). Not available on
all platforms.
Dir::delete( path)
Deletes the directory specified by path. The directory must be empty.
Dir::entries( path)
Returns an array of filenames in directory path.
Dir::getwd
Dir::pwd
Returns the current directory.
Dir::new( path)
Dir::open( path)
Dir::open( path) {| dir| ...}
Returns a new directory object for path. If open is given a block, a new
directory object is passed to the block, which closes the directory object
before terminating.
10
Dir::pwd
See Dir::getwd.
11
Dir::rmdir( path)
Dir::unlink( path)
Dir::delete( path)
Deletes the directory specified by path. The directory must be empty.
150
Ruby
Instance Methods
Assuming d is an instance of Dir class:
SN
1
d.each {| f| ...}
Executes the block once for each entry in d.
d.pos
d.tell
Returns the current position in d.
d.pos= offset
Sets the position in the directory stream.
d.pos= pos
d.seek(po s)
Moves to a position in d. pos must be a value returned by d.pos or 0.
d.read
Returns the next entry from d.
d.rewind
Moves position in d to the first entry.
d.seek(po s)
See d.pos=pos.
d.tell
See d.pos.
151
20. EXCEPTIONS
Ruby
The execution and the exception always go together. If you are opening a file,
which does not exist, then if you did not handle this situation properly, then your
program is considered to be of bad quality.
The program stops if an exception occurs. So exceptions are used to handle
various type of errors, which may occur during a program execution and take
appropriate action instead of halting program completely.
Ruby provide a nice mechanism to handle exceptions. We enclose the code that
could raise an exception in a begin/end block and use rescue clauses to tell Ruby
the types of exceptions we want to handle.
Syntax
begin
# rescue OneTypeOfException
# rescue AnotherTypeOfException
# else
# Other exceptions
ensure
# Always will be executed
end
Everything from begin to rescue is protected. If an exception occurs during the
execution of this block of code, control is passed to the block between rescue
and end.
For each rescue clause in the begin block, Ruby compares the raised Exception
against each of the parameters in turn. The match will succeed if the exception
named in the rescue clause is the same as the type of the currently thrown
exception, or is a superclass of that exception.
In an event, that an exception does not match any of the error types specified,
we are allowed to use an else clause after all the rescue clauses.
152
Ruby
Example
#!/usr/bin/ruby
begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
file = STDIN
end
print file, "==", STDIN, "\n"
This will produce the following result. You can see that STDIN is substituted to
file because open failed.
#<IO:0xb7d16f84>==#<IO:0xb7d16f84>
Syntax
begin
# Exceptions raised by this code will
# be caught by the following rescue clause
rescue
# This block will capture all types of exceptions
retry
end
153
Ruby
Example
#!/usr/bin/ruby
begin
file = open("/unexistant_file")
if file
puts "File opened successfully"
end
rescue
fname = "existant_file"
retry
end
The following is the flow of the process:
NOTE: Notice that if the file of re-substituted name does not exist this example
code retries infinitely. Be careful if you use retry for an exception process.
Syntax
raise
OR
154
Ruby
OR
OR
Example
#!/usr/bin/ruby
begin
puts 'I am before the raise.'
raise 'An error has occurred.'
puts 'I am after the raise.'
rescue
puts 'I am rescued.'
end
puts 'I am after the begin block.'
This will produce the following result:
I am before the raise.
I am rescued.
I am after the begin block.
155
Ruby
begin
raise 'A test exception.'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
end
This will produce the following result:
A test exception.
["main.rb:4"]
Syntax
begin
#.. process
#..raise exception
rescue
#.. handle error
ensure
#.. finally ensure execution
#.. This will always execute.
end
156
Ruby
Example
begin
raise 'A test exception.'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
ensure
puts "Ensuring execution"
end
This will produce the following result:
A test exception.
["main.rb:4"]
Ensuring execution
Syntax
begin
#.. process
#..raise exception
rescue
# .. handle error
else
#.. executes if there is no exception
ensure
#.. finally ensure execution
#.. This will always execute.
end
157
Ruby
Example
begin
# raise 'A test exception.'
puts "I'm not raising exception"
rescue Exception => e
puts e.message
puts e.backtrace.inspect
else
puts "Congratulations-- no errors!"
ensure
puts "Ensuring execution"
end
This will produce the following result:
I'm not raising exception
Congratulations-- no errors!
Ensuring execution
Raised error message can be captured using $! variable.
Syntax
throw :lablename
#.. this will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end
158
Ruby
OR
Example
The following example uses a throw to terminate interaction with the user if '!' is
typed in response to any prompt.
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == "!"
return res
end
catch :quitRequested do
name = promptAndGet("Name: ")
age = promptAndGet("Age: ")
sex = promptAndGet("Sex: ")
# ..
# process information
end
promptAndGet("Name:")
You should try the above program on your machine because it needs manual
interaction. This will produce the following result:
Name: Ruby on Rails
Age: 3
Sex: !
Name:Just Ruby
159
Ruby
Class Exception
Ruby's standard classes and modules raise exceptions. All the exception classes
form a hierarchy, with the class Exception at the top. The next level contains
seven different types:
Interrupt
NoMemoryError
SignalException
ScriptError
StandardError
SystemExit
There is one other exception at this level, Fatal, but the Ruby interpreter only
uses this internally.
Both ScriptError and StandardError have a number of subclasses, but we do not
need to go into the details here. The important thing is that if we create our own
exception classes, they need to be subclasses of either class Exception or one of
its descendants.
Let's look at an example:
class FileSaveError < StandardError
attr_reader :reason
def initialize(reason)
@reason = reason
end
end
Now, look at the following example, which will use this exception:
File.open(path, "w") do |file|
begin
# Write out the data ...
rescue
# Something went wrong!
raise FileSaveError.new($!)
end
end
160
Ruby
161
Ruby
162
Ruby
# define a class
163
Ruby
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# accessor methods
def printWidth
@width
end
def printHeight
@height
end
end
# create an object
box = Box.new(10, 20)
164
Ruby
#!/usr/bin/ruby -w
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# accessor methods
def getWidth
@width
end
def getHeight
@height
end
# setter methods
def setWidth=(value)
@width = value
end
def setHeight=(value)
@height = value
end
end
# create an object
box = Box.new(10, 20)
Ruby
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end
# create an object
box = Box.new(10, 20)
166
Ruby
class Box
# Initialize our class variables
@@count = 0
def initialize(w,h)
# assign instance avriables
@width, @height = w, h
@@count += 1
end
def self.printCount()
puts "Box count is : #@@count"
end
end
Ruby
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# define to_s method
def to_s
"(w:#@width,h:#@height)"
end
end
# create an object
box = Box.new(10, 20)
Ruby
Access Control
Ruby gives you three levels of protection at instance methods level, which may
be public, private, or protected. Ruby does not apply any access control over
instance and class variables.
Following is a simple example to show the syntax of all the three access
modifiers:
#!/usr/bin/ruby -w
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
Ruby
@height
end
# make them private
private :getWidth, :getHeight
# create an object
box = Box.new(10, 20)
170
Ruby
Class Inheritance
One of the most important concepts in object-oriented programming is that of
inheritance. Inheritance allows us to define a class in terms of another class,
which makes it easier to create and maintain an application.
Inheritance also provides an opportunity to reuse the code functionality and fast
implementation time but unfortunately Ruby does not support multiple levels of
inheritances but Ruby supports mixins. A mixin is like a specialized
implementation of multiple inheritance in which only the interface portion is
inherited.
When creating a class, instead of writing completely new data members and
member functions, the programmer can designate that the new class should
inherit the members of an existing class. This existing class is called the base
class or superclass, and the new class is referred to as the derived class or
sub-class.
Ruby also supports the concept of subclassing, i.e., inheritance and following
example explains the concept. The syntax for extending a class is simple. Just
add a < character and the name of the superclass to your class statement. For
example, following define a class BigBox as a subclass of Box:
#!/usr/bin/ruby -w
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end
# define a subclass
class BigBox < Box
Ruby
def printArea
@area = @width * @height
puts "Big box area is : #@area"
end
end
# create an object
box = BigBox.new(10, 20)
Methods Overriding
Though you can add new functionality in a derived class, but sometimes you
would like to change the behavior of already defined method in a parent class.
You can do so simply by keeping the method name same and overriding the
functionality of the method as shown below in the example:
#!/usr/bin/ruby -w
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end
172
Ruby
# define a subclass
class BigBox < Box
# create an object
box = BigBox.new(10, 20)
Operator Overloading
We'd like the + operator to perform vector addition of two Box objects using +,
the * operator to multiply a Box width and height by a scalar, and the unary operator to do negate the width and height of the Box. Here is a version of the
Box class with mathematical operators defined:
class Box
def initialize(w,h) # Initialize the width and height
@width,@height = w, h
end
def +(other)
def -@
Box.new(-@width, -@height)
173
Ruby
end
def *(scalar)
Box.new(@width*scalar, @height*scalar)
end
end
Freezing Objects
Sometimes, we want to prevent an object from being changed. The freeze
method in Object allows us to do this, effectively turning an object into a
constant. Any object can be frozen by invoking Object.freeze. A frozen object
may not be modified: you can't change its instance variables.
You can check if a given object is already frozen or not using Object.frozen?
method, which returns true in case the object is frozen otherwise a false value is
return. Following example clears the concept:
#!/usr/bin/ruby -w
# define a class
class Box
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# accessor methods
def getWidth
@width
end
def getHeight
@height
end
# setter methods
def setWidth=(value)
174
Ruby
@width = value
end
def setHeight=(value)
@height = value
end
end
# create an object
box = Box.new(10, 20)
Ruby
Class Constants
You can define a constant inside a class by assigning a direct numeric or string
value to a variable, which is defined without using either @ or @@. By
convention, we keep constant names in upper case.
Once a constant is defined, you cannot change its value but you can access a
constant directly inside a class much like a variable but if you want to access a
constant outside of the class then you would have to use classname::constant
as shown in the below example.
#!/usr/bin/ruby -w
# define a class
class Box
BOX_COMPANY = "TATA Inc"
BOXWEIGHT = 10
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end
# create an object
box = Box.new(10, 20)
Ruby
# define a class
class Box
attr_accessor :width, :height
# constructor method
def initialize(w,h)
@width, @height = w, h
end
# instance method
def getArea
@width * @height
end
end
Ruby
a = box1.getArea()
puts "Area of the box is : #{a}"
Class Information
If class definitions are executable code, this implies that they execute in the
context of some object: self must reference something. Let's find out what it is.
#!/usr/bin/ruby -w
class Box
# print class information
puts "Type of self = #{self.type}"
puts "Name of self = #{self.name}"
end
When the above code is executed, it produces the following result:
Type of self = Class
Name of self = Box
This means that a class definition is executed with that class as the current
object. This means that methods in the metaclass and its superclasses will be
available during the execution of the method definition.
178
Ruby
Syntax
/pattern/
/pattern/im
Example
#!/usr/bin/ruby
if ( line1 =~ /Cats(.*)/ )
puts "Line1 contains Cats"
end
if ( line2 =~ /Cats(.*)/ )
puts "Line2 contains
Dogs"
end
This will produce the following result:
Line1 contains Cats
Regular-Expression Modifiers
Regular expression literals may include an optional modifier to control various
aspects of matching. The modifier is specified after the second slash character,
as shown previously and may be represented by one of these characters:
179
Ruby
Modifier
Description
u,e,s,n
Like string literals delimited with %Q, Ruby allows you to begin your regular
expressions with %r followed by a delimiter of your choice. This is useful when
the pattern you are describing contains a lot of forward slash characters that you
don't want to escape:
# Following matches a single slash character, no escape required
%r|/|
Regular-Expression Patterns
Except for control characters, (+ ? . * ^ $ ( ) [ ] { } | \), all characters match
themselves. You can escape a control character by preceding it with a backslash.
Following table lists the regular expression syntax that is available in Ruby.
Pattern
^
Description
Matches beginning of line.
180
Ruby
[...]
[^...]
re*
re+
re?
re{ n}
re{ n,}
re{ n, m}
a| b
Matches either a or b.
(re)
(?imx)
(?-imx)
(?: re)
(?imx: re)
Temporarily toggles
parentheses.
on
i,
m,
or
options
within
181
Ruby
(?-imx: re)
Temporarily toggles
parentheses.
off
i,
m,
or
options
within
(?#...)
Comment.
(?= re)
(?! re)
(?> re)
\w
\W
\s
\S
Matches nonwhitespace.
\d
\D
Matches nondigits.
\A
\Z
\z
\G
\b
\B
182
Ruby
Regular-Expression Examples
Literal Characters
Example
/ruby/
Description
Matches "ruby".
Matches Yen sign. Multibyte characters are supported in
Ruby 1.9 and Ruby 1.8.
Character Classes
Example
Description
/[Rr]uby/
/rub[ye]/
/[aeiou]/
/[0-9]/
/[a-z]/
/[A-Z]/
/[a-zA-Z0-9]/
Ruby
/[^aeiou]/
/[^0-9]/
Description
Matches any character except newline.
/./m
/\d/
/\D/
/\s/
/\S/
/\w/
/\W/
Repetition Cases
Example
Description
/ruby?/
/ruby*/
/ruby+/
/\d{3}/
184
Ruby
/\d{3,}/
/\d{3,5}/
Matches 3, 4, or 5 digits.
Nongreedy Repetition
This matches the smallest number of repetitions:
Example
Description
/<.*>/
/<.*?>/
Description
No group: + repeats \d
Grouped: + repeats \D\d pair
Match "Ruby", "Ruby, ruby, ruby", etc.
Back References
This matches a previously matched group again:
Example
Description
/([Rr])uby&\1ails/
/(['"])(?:(?!\1).)*\1/
185
Ruby
Alternatives
Example
Description
/ruby|rube/
/rub(y|le))/
/ruby(!+|\?)/
Anchors
It needs to specify match position.
Example
Description
/^Ruby/
/Ruby$/
/\ARuby/
/Ruby\Z/
/\bRuby\b/
/\brub\B/
/Ruby(?=!)/
/Ruby(?!!)/
186
Ruby
Description
/R(?#comment)/
/R(?i)uby/
/R(?i:uby)/
Same as above.
/rub(?:y|le))/
187
Ruby
puts "#{text}"
This will produce the following result:
Rails are Rails, really good Ruby on Rails
188
23. DBI
Ruby
This chapter teaches you how to access a database using Ruby. The Ruby DBI
module provides a database-independent interface for Ruby scripts similar to
that of the Perl DBI module.
DBI stands for Database Independent Interface for Ruby, which means DBI
provides an abstraction layer between the Ruby code and the underlying
database, allowing you to switch database implementations really easily. It
defines a set of methods, variables, and conventions that provide a consistent
database interface, independent of the actual database being used.
DBI can interface with the following:
DB2
Frontbase
mSQL
MySQL
ODBC
Oracle
OCI8 (Oracle)
PostgreSQL
Proxy/Server
SQLite
SQLRelay
189
Ruby
Prerequisites
If you want to write Ruby scripts to access MySQL databases, you'll need to
have the Ruby MySQL module installed.
This module acts as a DBD as explained above and can be downloaded
fromhttp://www.tmtm.org/en/mysql/ruby/.
Step 1
$ tar zxf dbi-0.2.0.tar.gz
190
Ruby
Step 2
Go in distribution directory dbi-0.2.0 and configure it using the setup.rb script in
that directory. The most general configuration command looks like this, with no
arguments following the config argument. This command configures the
distribution to install all drivers by default.
$ ruby setup.rb config
To be more specific, provide a --with option that lists the particular parts of the
distribution you want to use. For example, to configure only the main DBI
module and the MySQL DBD-level driver, issue the following command:
$ ruby setup.rb config --with=dbi,dbd_mysql
Step 3
Final step is to build the driver and install it using the following commands:
$ ruby setup.rb setup
$ ruby setup.rb install
Database Connection
Assuming we are going to work with MySQL database, before connecting to a
database make sure of the following:
require "dbi"
begin
191
Ruby
#{e.err}"
INSERT Operation
INSERT operation is required when you want to create your records into a
database table.
Once a database connection is established, we are ready to create tables or
records into the database tables using do method or prepare and execute
method.
Using do Statement
Statements that do not return rows can be issued by invoking the do database
handle method. This method takes a statement string argument and returns a
count of the number of rows affected by the statement.
dbh.do("DROP TABLE IF EXISTS EMPLOYEE")
dbh.do("CREATE TABLE EMPLOYEE (
192
Ruby
FIRST_NAME
LAST_NAME
AGE INT,
SEX CHAR(1),
INCOME FLOAT )" );
Similarly, you can execute the SQL INSERT statement to create a record into the
EMPLOYEE table.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
dbh.do( "INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME,
AGE,
SEX,
INCOME)
VALUES ('Mac', 'Mohan', 20, 'M', 2000)" )
puts "Record has been created"
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
Ruby
Preparing SQL statement with INSERT statement. This will be done using
the prepare method.
Executing SQL query to select all the results from the database. This will
be done using the execute method.
If everything goes fine, then commit this operation otherwise you can
rollback the complete transaction.
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare( "INSERT INTO EMPLOYEE(FIRST_NAME,
LAST_NAME,
AGE,
194
Ruby
SEX,
INCOME)
VALUES (?, ?, ?, ?, ?)" )
sth.execute('John', 'Poul', 25, 'M', 2300)
sth.execute('Zara', 'Ali', 17, 'F', 1000)
sth.finish
dbh.commit
puts "Record has been created"
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
READ Operation
READ Operation on any database means to fetch some useful information from
the database.
Once our database connection is established, we are ready to make a query into
this database. We can use either do method or prepare and execute methods to
fetch values from a database table.
Record fetching takes following steps:
Preparing SQL query based on required conditions. This will be done using
the prepare method.
Executing SQL query to select all the results from the database. This will
be done using the execute method.
Fetching all the results one by one and printing those results. This will be
done using the fetch method.
195
Ruby
Releasing Statement handle. This will be done using the finish method.
Following is the procedure to query all the records from EMPLOYEE table having
salary more than 1000.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("SELECT * FROM EMPLOYEE
WHERE INCOME > ?")
sth.execute(1000)
sth.fetch do |row|
printf "First Name: %s, Last Name : %s\n", row[0], row[1]
printf "Age: %d, Sex : %s\n", row[2], row[3]
printf "Salary :%d \n\n", row[4]
end
sth.finish
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
Ruby
197
Ruby
10
11
12
sth.cancel
Frees the resources held by the result-set. After calling this method, it is
no longer possible to fetch rows until you again call execute.
13
sth.finish
Frees the resources held by the prepared statement. After calling this
method no further methods can be called onto this object.
198
Ruby
Description
DBI::SQL_FETCH_FIRST
DBI::SQL_FETCH_LAST
DBI::SQL_FETCH_NEXT
DBI::SQL_FETCH_PRIOR
DBI::SQL_FETCH_ABSOLUTE
DBI::SQL_FETCH_RELATIVE
Example
The following example shows how to get the metadata for a statement. Consider
the EMPLOYEE table, which we created in the last chapter.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("SELECT * FROM EMPLOYEE
WHERE INCOME > ?")
sth.execute(1000)
if sth.column_names.size == 0 then
puts "Statement has no result set"
199
Ruby
%s\n", info["sql_type"]
printf "type_name:
%s\n", info["type_name"]
printf "precision:
%s\n", info["precision"]
printf "scale:
%s\n", info["scale"]
printf "nullable:
%s\n", info["nullable"]
printf "indexed:
%s\n", info["indexed"]
printf "primary:
%s\n", info["primary"]
printf "unique:
%s\n", info["unique"]
printf "mysql_type:
%s\n", info["mysql_type"]
printf "mysql_type_name:
%s\n", info["mysql_type_name"]
printf "mysql_length:
%s\n", info["mysql_length"]
%s\n", info["mysql_flags"]
end
end
sth.finish
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
Ruby
12
type_name:
VARCHAR
precision:
20
scale:
nullable:
true
indexed:
false
primary:
false
unique:
false
mysql_type:
254
mysql_type_name:
VARCHAR
mysql_length:
20
mysql_max_length: 4
mysql_flags:
12
type_name:
VARCHAR
precision:
20
scale:
nullable:
true
indexed:
false
primary:
false
unique:
false
mysql_type:
254
mysql_type_name:
VARCHAR
mysql_length:
20
mysql_max_length: 5
mysql_flags:
0
201
Ruby
type_name:
INTEGER
precision:
11
scale:
nullable:
true
indexed:
false
primary:
false
unique:
false
mysql_type:
mysql_type_name:
INT
mysql_length:
11
mysql_max_length: 2
mysql_flags:
32768
12
type_name:
VARCHAR
precision:
scale:
nullable:
true
indexed:
false
primary:
false
unique:
false
mysql_type:
254
mysql_type_name:
VARCHAR
mysql_length:
mysql_max_length: 1
mysql_flags:
type_name:
FLOAT
precision:
12
scale:
31
202
Ruby
nullable:
true
indexed:
false
primary:
false
unique:
false
mysql_type:
mysql_type_name:
FLOAT
mysql_length:
12
mysql_max_length: 4
mysql_flags:
32768
Update Operation
UPDATE Operation on any database means to update one or more records,
which are already available in the database. Following is the procedure to update
all the records having SEX as 'M'. Here, we will increase AGE of all the males by
one year. This will take three steps:
Preparing SQL query based on required conditions. This will be done using
the prepare method.
Executing SQL query to select all the results from the database. This will
be done using the execute method.
Releasing Statement handle. This will be done using the finish method.
If everything goes fine then commit this operation otherwise you can
rollback the complete transaction.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("UPDATE EMPLOYEE SET AGE = AGE + 1
WHERE SEX = ?")
sth.execute('M')
203
Ruby
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
DELETE Operation
DELETE operation is required when you want to delete some records from your
database. Following is the procedure to delete all the records from EMPLOYEE
where AGE is more than 20. This operation will take following steps.
Preparing SQL query based on required conditions. This will be done using
the prepare method.
Executing SQL query to delete required records from the database. This
will be done using the execute method.
Releasing Statement handle. This will be done using the finish method.
If everything goes fine then commit this operation otherwise you can
rollback the complete transaction.
#!/usr/bin/ruby -w
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123")
sth = dbh.prepare("DELETE FROM EMPLOYEE
WHERE AGE > ?")
204
Ruby
sth.execute(20)
sth.finish
dbh.commit
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
Performing Transactions
Transactions are a mechanism that ensures data consistency. Transactions
should have the following four properties:
The DBI provides two methods to either commit or rollback a transaction. There
is one more method called transaction, which can be used to implement
transactions. There are two simple approaches to implement transactions:
Approach I
The first approach uses DBI's commit and rollback methods to explicitly commit
or cancel the transaction:
dbh['AutoCommit'] = false # Set auto commit to false.
begin
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
205
Ruby
Approach II
The second approach uses the transaction method. This is simpler, because it
takes a code block containing the statements that make up the transaction. The
transaction method executes the block, then invokes commit or rollback
automatically, depending on whether the block succeeds or fails:
dbh['AutoCommit'] = false # Set auto commit to false.
dbh.transaction do |dbh|
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'John'")
dbh.do("UPDATE EMPLOYEE SET AGE = AGE+1
WHERE FIRST_NAME = 'Zara'")
end
dbh['AutoCommit'] = true
COMMIT Operation
Commit is the operation, which gives a green signal to database to finalize the
changes, and after this operation, no change can be reverted back.
Here is a simple example to call the commit method.
dbh.commit
206
Ruby
ROLLBACK Operation
If you are not satisfied with one or more of the changes and you want to revert
back those changes completely, then use the rollback method.
Here is a simple example to call the rollback method.
dbh.rollback
Disconnecting Database
To disconnect Database connection, use disconnect API.
dbh.disconnect
If the connection to a database is closed by the user with the disconnect
method, any outstanding transactions are rolled back by the DBI. However,
instead of depending on any of DBI's implementation details, your application
would be better off calling the commit or rollback explicitly.
Handling Errors
There are many sources of errors. A few examples are a syntax error in an
executed SQL statement, a connection failure, or calling the fetch method for an
already canceled or finished statement handle.
If a DBI method fails, DBI raises an exception. DBI methods may raise any of
several types of exception but the two most important exception classes are
DBI::InterfaceError and DBI::DatabaseError.
Exception objects of these classes have three attributes named err, errstr, and
state, which represent the error number, a descriptive error string, and a
standard error code. The attributes are explained below:
Ruby
#{e.err}"
trace(mode, destination)
The mode value may be 0 (off), 1, 2, or 3, and the destination should be an IO
object. The default values are 2 and STDERR, respectively.
Example 1
DBI.connect can take a code block, passes the database handle to it, and
automatically disconnects the handle at the end of the block as follows.
208
Ruby
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
"testuser", "test123") do |dbh|
Example 2
dbh.prepare can take a code block, passes the statement handle to it, and
automatically calls finish at the end of the block as follows.
dbh.prepare("SHOW DATABASES") do |sth|
sth.execute
puts "Databases: " + sth.fetch_all.join(", ")
end
Example 3
dbh.execute can take a code block, passes the statement handle to it, and
automatically calls finish at the end of the block as follows:
dbh.execute("SHOW DATABASES") do |sth|
puts "Databases: " + sth.fetch_all.join(", ")
end
DBI transaction method also takes a code block, which has been described
above.
dbh.func(:createdb, db_name)
Creates a new database.
dbh.func(:dropdb, db_name)
Drops a database.
209
Ruby
dbh.func(:reload)
Performs a reload operation.
dbh.func(:shutdown)
Shuts down the server.
10
11
12
Example
#!/usr/bin/ruby
require "dbi"
begin
# connect to the MySQL server
dbh = DBI.connect("DBI:Mysql:TESTDB:localhost",
210
Ruby
"testuser", "test123")
puts dbh.func(:client_info)
puts dbh.func(:client_version)
puts dbh.func(:host_info)
puts dbh.func(:proto_info)
puts dbh.func(:server_info)
puts dbh.func(:thread_id)
puts dbh.func(:stat)
rescue DBI::DatabaseError => e
puts "An error occurred"
puts "Error code:
#{e.err}"
Threads: 1
Flush tables: 1
Questions: 1101078
Open tables: 64
Slow queries: 4 \
\
211
Ruby
Using cgi.rb
Ruby comes with a special library called cgi that enables more sophisticated
interactions than those with the preceding CGI script.
Let's create a basic CGI script that uses cgi:
212
Ruby
#!/usr/bin/ruby
require 'cgi'
cgi = CGI.new
puts cgi.header
puts "<html><body>This is a test</body></html>"
Here, you created a CGI object and used it to print the header line for you.
Form Processing
Using class CGI gives you access to HTML query parameters in two ways.
Suppose we are given a URL of /cgi-bin/test.cgi?FirstName=Zara&LastName=Ali.
You can access the parameters FirstName and LastName using CGI#[] directly as
follows:
#!/usr/bin/ruby
require 'cgi'
cgi = CGI.new
cgi['FirstName'] # =>
["Zara"]
cgi['LastName']
["Ali"]
# =>
There is another way to access these form variables. This code will give you a
hash of all the key and values:
#!/usr/bin/ruby
require 'cgi'
cgi = CGI.new
h = cgi.params
# =>
{"FirstName"=>["Zara"],"LastName"=>["Ali"]}
h['FirstName']
# =>
["Zara"]
h['LastName']
# =>
["Ali"]
213
Ruby
require 'cgi'
cgi = CGI.new
cgi.keys
# =>
["FirstName", "LastName"]
If a form contains multiple fields with the same name, the corresponding values
will be returned to the script as an array. The [] accessor returns just the first of
these.index the result of the params method to get them all.
In this example, assume the form has three fields called "name" and we entered
three names "Zara", "Huma" and "Nuha":
#!/usr/bin/ruby
require 'cgi'
cgi = CGI.new
cgi['name']
# => "Zara"
# => ["name"]
cgi.params
Note: Ruby will take care of GET and POST methods automatically. There is no
separate treatment for these two different methods.
An associated, but basic, form that could send the correct data would have the
HTML code like so:
<html>
<body>
<form method="POST" action="http://www.example.com/test.cgi">
First Name :<input type="text" name="FirstName" value="" />
<br />
Last Name :<input type="text" name="LastName" value="" />
Ruby
</body>
</html>
require "cgi"
cgi = CGI.new("html4")
cgi.out{
cgi.html{
cgi.head{ "\n"+cgi.title{"This Is a Test"} } +
cgi.body{ "\n"+
cgi.form{"\n"+
cgi.hr +
cgi.h1 { "A Form: " } + "\n"+
cgi.textarea("get_text") +"\n"+
cgi.br +
cgi.submit
}
}
}
}
NOTE: The form method of the CGI class can accept a method parameter, which
will set the HTTP method ( GET, POST, and so on...) to be used on form
submittal. The default, used in this example, is POST.
215
Ruby
Quoting Strings
When dealing with URLs and HTML code, you must be careful to quote certain
characters. For instance, a slash character ( / ) has special meaning in a URL, so
it must be escaped if it's not part of the pathname.
For example, any / in the query portion of the URL will be translated to the
string %2F and must be translated back to a / for you to use it. Space and
ampersand are also special characters. To handle this, CGI provides the routines
CGI.escape and CGI.unescape.
#!/usr/bin/ruby
require 'cgi'
puts CGI.escape(Zara Ali/A Sweet & Sour Girl")
216
Ruby
require 'cgi'
puts CGI.escapeHTML('<h1>Zara Ali/A Sweet & Sour Girl</h1>')
This will produce the following result:
<h1>Zara Ali/A Sweet & Sour Girl</h1>'
Ruby CGI
CGI Class Methods
Here is a list of CGI Class methods:
SN
1
CGI::escape( str)
217
Ruby
CGI::unescape( str)
Expands a string that has been escaped using URL-encoding.
CGI::escapeHTML( str)
Escapes HTML special characters, including: & < >.
CGI::unescapeHTML( str)
Expands escaped HTML special characters, including: & < >.
specified HTML
CGI::parse( query)
Parses the query and returns a hash containing its key-value pairs.
10
CGI::rfc1123_date( time)
Formats the data and time according to RFC-1123 (for example, Tue, 2
Jun 2008 00:00:00 GMT).
Ruby
c[ name]
Returns an array containing the value of the field name corresponding to
name.
c.cookies
Returns a hash containing a CGI::Cookie object containing keys and
values from a cookie.
c.header([ header])
Returns a CGI header containing the information in header. If header is a
hash, its key-value pairs are used to create the header.
219
Ruby
10
c.keys
Returns an array containing the field names from the form.
11
c.key?( name)
c.has_key?( name)
c.include?( name)
Returns true if the form contains the specified field name.
12
13
14
c.params
Returns a hash containing field names and values from the form.
15
c.params= hash
Sets field names and values in the form using a hash.
16
17
Ruby
c.scrolling_list( options)
Returns an HTML string defining a pop-up menu. Tag attributes may be
specified in a hash passed as an argument.
18
19
20
21
22
221
Ruby
require "cgi"
cgi = CGI.new("html4")
cgi.out{
cgi.html{
cgi.head{ "\n"+cgi.title{"This Is a Test"} } +
cgi.body{ "\n"+
cgi.form{"\n"+
cgi.hr +
cgi.h1 { "A Form: " } + "\n"+
cgi.textarea("get_text") +"\n"+
cgi.br +
cgi.submit
}
}
}
}
Returned Value
accept
accept_charset
accept_encoding
Acceptable encoding
accept_language
Acceptable language
auth_type
Authentication type
raw_cookie
222
Ruby
content_length
Content length
content_type
Content type
From
gateway_interface
path_info
Extra path
path_translated
Query_string
Query string
referer
remote_addr
remote_host
Client hostname
remote_ident
Client name
remote_user
Authenticated user
request_method
script_name
Program name
server_name
Server name
server_port
Server port
server_protocol
Server protocol
server_software
Server software
user_agent
User agent
223
Ruby
How It Works?
Your server sends some data to the visitor's browser in
browser may accept the cookie. If it does, it is stored
the visitor's hard drive. Now, when the visitor arrives
site, the cookie is available for retrieval. Once
knows/remembers what was stored.
Expires: The date the cookie will expire. If this is blank, the cookie will
expire when the visitor quits the browser.
Path: The path to the directory or web page that sets the cookie. This
may be blank if you want to retrieve the cookie from any directory or
page.
Secure: If this field contains the word "secure", then the cookie may only
be retrieved with a secure server. If this field is blank, no such restriction
exists.
Name=Value: Cookies are set and retrieved in the form of key and value
pairs.
Ruby
#!/usr/bin/ruby
require "cgi"
cgi = CGI.new("html4")
cookie = CGI::Cookie.new('name' => 'mycookie',
'value' => 'Zara Ali',
'expires' => Time.now + 3600)
cgi.out('cookie' => cookie) do
cgi.head + cgi.body { "Cookie stored" }
end
The next time the user comes back to this page, you can retrieve the cookie
values set as shown below:
#!/usr/bin/ruby
require "cgi"
cgi = CGI.new("html4")
cookie = cgi.cookies['mycookie']
cgi.out('cookie' => cookie) do
cgi.head + cgi.body { cookie[0] }
end
Cookies are represented using a separate object of class CGI::Cookie, containing
the following accessors:
Attribute
Returned Value
name
Cookie name
value
path
domain
The domain
225
Ruby
expires
secure
require 'cgi'
require 'cgi/session'
cgi = CGI.new("html4")
cgi.out{
cgi.html {
cgi.body ("bgcolor" => sess["bgcolor"]){
"The background of this page"
Ruby
Class CGI::Session
A CGI::Session maintains a persistent state for web users in a CGI environment.
Sessions may be memory-resident or may be stored on disk.
Class Methods
Ruby class Class CGI::Session provides a single class method to create a
session:
CGI::Session::new( cgi[, option])
Starts a new CGI session and returns the corresponding CGI::Session object.
option may be an option hash specifying one or more of the following:
Instance Methods
SN
1
227
Ruby
[ ]=
Sets the value for the given key. See example above.
delete
Calls the delete method of the underlying database manager. For
FileStore, deletes the physical file containing the session. For
MemoryStore, removes the session from memory.
update
Calls the update method of the underlying database manager. For
FileStore, writes the session data out to disk. Has no effect with
MemoryStore.
228
Ruby
Simple Mail Transfer Protocol (SMTP) is a protocol, which handles sending e-mail
and routing e-mail between mail servers.
Ruby provides Net::SMTP class for Simple Mail Transfer Protocol (SMTP) clientside connection and provides two class methods new and start.
of
the
sender,
defaulting
to
An SMTP object has an instance method called sendmail, which will typically be
used to do the work of mailing a message. It takes three parameters:
The sender - A string that will appear in the from field of the email.
Example
Here is a simple way to send one email using Ruby script. Try it once:
require 'net/smtp'
message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
229
Ruby
Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, 'me@fromdomain.com',
'test@todomain.com'
end
Here, you have placed a basic e-mail in message, using a document, taking care
to format the headers correctly. E-mails require a From, To, and Subject
header, separated from the body of the e-mail with a blank line.
To send the mail you use Net::SMTP to connect to the SMTP server on the local
machine and then use the send_message method along with the message, the
from address, and the destination address as parameters (even though the from
and to addresses are within the e-mail itself, these aren't always used to route
mail).
If you're not running an SMTP server on your machine, you can use the
Net::SMTP to communicate with a remote SMTP server. Unless you're using a
webmail service (such as Hotmail or Yahoo! Mail), your e-mail provider will have
provided you with outgoing mail server details that you can supply to
Net::SMTP, as follows:
Net::SMTP.start('mail.your-domain.com')
This line of code connects to the SMTP server on port 25 of mail.yourdomain.com without using any username or password. If you need to, though,
you can specify port number and other details. For example:
Net::SMTP.start('mail.your-domain.com',
25,
'localhost',
'username', 'password' :plain)
This example connects to the SMTP server at mail.your-domain.com using a
username and password in plain text format. It identifies the client's hostname
as localhost.
230
Ruby
Example
Following is the example to send HTML content as an email. Try it once:
require 'net/smtp'
message = <<MESSAGE_END
From: Private Person <me@fromdomain.com>
To: A Test User <test@todomain.com>
MIME-Version: 1.0
Content-type: text/html
Subject: SMTP e-mail test
Net::SMTP.start('localhost') do |smtp|
smtp.send_message message, 'me@fromdomain.com',
'test@todomain.com'
end
Ruby
Example
Following is the example, which will send a file /tmp/test.txt as an attachment.
require 'net/smtp'
filename = "/tmp/test.txt"
# Read a file and encode it into base64 format
filecontent = File.read(filename)
encodedcontent = [filecontent].pack("m")
# base64
marker = "AUNIQUEMARKER"
body =<<EOF
This is a test email to send an attachement.
EOF
Ruby
Content-Transfer-Encoding:8bit
#{body}
--#{marker}
EOF
#{encodedcontent}
--#{marker}-EOF
233
Ruby
Ruby provides two levels of access to network services. At a low level, you can
access the basic socket support in the underlying operating system, which allows
you to implement clients and servers for both connection-oriented and
connectionless protocols.
Ruby also has libraries that provide higher-level access to specific applicationlevel network protocols, such as FTP, HTTP, and so on.
This chapter gives you an understanding on most famous concept in Networking
- Socket Programming.
Description
domain
type
protocol
hostname
234
Ruby
Each server listens for clients calling on one or more ports. A port
may be a Fixnum port number, a string containing a port number,
or the name of a service.
A Simple Client
Here we will write a very simple client program, which will open a connection to
a given port and given host. Ruby class TCPSocket provides open function to
open such a socket.
The TCPSocket.open(hosname, port) opens a TCP connection to hostname on
the port.
Once you have a socket open, you can read from it like any IO object. When
done, remember to close it, as you would close a file.
The following code is a very simple client that connects to a given host and port,
reads any available data from the socket, and then exits:
require 'socket'
hostname = 'localhost'
port = 2000
s = TCPSocket.open(hostname, port)
end
s.close
235
Ruby
A Simple Server
To write Internet servers, we use the TCPServer class. A TCPServer object is a
factory for TCPSocket objects.
Now call TCPServer.open(hostname, port function to specify a port for your
service and create a TCPServer object.
Next, call the accept method of the returned TCPServer object. This method
waits until a client connects to the port you specified, and then returns a
TCPSocket object that represents the connection to that client.
require 'socket'
server = TCPServer.open(2000)
loop {
client = server.accept
client.puts(Time.now.ctime)
}
Now, run this server in background and then run the above client to see the
result.
server = TCPServer.open(2000)
loop {
Thread.start(server.accept) do |client|
client.puts(Time.now.ctime) # Send the time to the client
client.puts "Closing the connection. Bye!"
236
Ruby
client.close
end
}
In this example, you have a permanent loop, and when server.accept responds,
a new thread is created and started immediately to handle the connection that
has just been accepted, using the connection object passed into the thread.
However, the main program immediately loops back and awaits new
connections.
Using Ruby threads in this way means the code is portable and will run in the
same way on Linux, OS X, and Windows.
host = 'www.tutorialspoint.com'
port = 80
path = "/index.htm"
socket = TCPSocket.open(host,port)
# Connect to server
socket.print(request)
# Send request
response = socket.read
# And display it
To implement the similar web client, you can use a pre-built library like
Net::HTTP for working with HTTP. Here is the code that does the equivalent of
the previous code:
237
Ruby
require 'net/http'
host = 'www.tutorialspoint.com'
path = '/index.htm'
http = Net::HTTP.new(host)
# Create a connection
if headers.code == "200"
print body
else
puts "#{headers.code} #{headers.message}"
end
Please check similar libraries to work with FTP, SMTP, POP, and IMAP protocols.
Further Readings
We have given you a quick start on Socket Programming. It is a big subject, so
it is recommended that you go through Ruby Socket Library and Class
Methods to find more details.
238
Ruby
What is XML?
The Extensible Markup Language (XML) is a markup language much like HTML or
SGML. This is recommended by the World Wide Web Consortium and available
as an open standard.
XML is a portable, open source language that allows programmers to develop
applications that can be read by other applications, regardless of operating
system and/or developmental language.
XML is extremely useful for keeping track of small to medium amounts of data
without requiring a SQL-based backbone.
SAX obviously can't process information as fast as DOM can when working with
large files. On the other hand, using DOM exclusively can really kill your
resources, especially if used on a lot of small files.
SAX is read-only, while DOM allows changes to the XML file. Since these two
different APIs literally complement each other there is no reason why you can't
use them both for large projects.
239
Ruby
For all our XML code examples, let's use a simple XML file as an input:
<collection shelf="New Arrivals">
<movie title="Enemy Behind">
<type>War, Thriller</type>
<format>DVD</format>
<year>2003</year>
<rating>PG</rating>
<stars>10</stars>
<description>Talk about a US-Japan war</description>
</movie>
<movie title="Transformers">
<type>Anime, Science Fiction</type>
<format>DVD</format>
<year>1989</year>
<rating>R</rating>
<stars>8</stars>
<description>A schientific fiction</description>
</movie>
<movie title="Trigun">
<type>Anime, Action</type>
<format>DVD</format>
<episodes>4</episodes>
240
Ruby
<rating>PG</rating>
<stars>10</stars>
<description>Vash the Stampede!</description>
</movie>
<movie title="Ishtar">
<type>Comedy</type>
<format>VHS</format>
<rating>PG</rating>
<stars>2</stars>
<description>Viewable boredom</description>
</movie>
</collection>
DOM-like Parsing
Let's first parse our XML data in tree fashion. We begin by requiring the
rexml/document library; often we do an include REXML to import into the toplevel namespace for convenience.
#!/usr/bin/ruby -w
require 'rexml/document'
include REXML
xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)
Ruby
SAX-like Parsing
To process the same data, movies.xml, file in a stream-oriented way we will
define a listener class whose methods will be the target of callbacks from the
parser.
NOTE: It is not suggested to use SAX-like parsing for a small file, this is just for
a demo example.
242
Ruby
#!/usr/bin/ruby -w
require 'rexml/document'
require 'rexml/streamlistener'
include REXML
class MyListener
include REXML::StreamListener
def tag_start(*args)
puts "tag_start: #{args.map {|x| x.inspect}.join(', ')}"
end
def text(data)
return if data =~ /^\w*$/
# whitespace only
text
#{abbrev.inspect}"
end
end
list = MyListener.new
xmlfile = File.new("movies.xml")
Document.parse_stream(xmlfile, list)
This will produce the following result:
tag_start: "collection", {"shelf"=>"New Arrivals"}
tag_start: "movie", {"title"=>"Enemy Behind"}
tag_start: "type", {}
text
"War, Thriller"
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
243
Ruby
tag_start: "stars", {}
tag_start: "description", {}
text
tag_start: "format", {}
tag_start: "year", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text
"Anime, Action"
tag_start: "format", {}
tag_start: "episodes", {}
tag_start: "rating", {}
tag_start: "stars", {}
tag_start: "description", {}
text
"Viewable boredom"
Ruby
REXML has XPath support via the XPath class. It assumes tree-based parsing
(document object model) as we have seen above.
#!/usr/bin/ruby -w
require 'rexml/document'
include REXML
xmlfile = File.new("movies.xml")
xmldoc = Document.new(xmlfile)
245
Ruby
Ruby-Sablotron:
This parser is written and maintained by Masayoshi Takahashi. This is written
primarily for Linux OS and requires the following libraries:
Sablot
Iconv
Expat
XSLT4R
XSLT4R is written by Michael Neumann and can be found at the RAA in the
Library section under XML. XSLT4R uses a simple commandline interface, though
it can alternatively be used within a third-party application to transform an XML
document.
XSLT4R needs XMLScan to operate, which is included within the XSLT4R archive
and which is also a 100 percent Ruby module. These modules can be installed
using standard Ruby installation method (i.e., ruby install.rb).
XSLT4R has the following syntax:
ruby xslt.rb stylesheet.xsl document.xml [arguments]
If you want to use XSLT4R from within an application, you can include XSLT and
input the parameters you need. Here is the example:
require "xslt"
stylesheet = File.readlines("stylesheet.xsl").to_s
xml_doc = File.readlines("document.xml").to_s
arguments = { 'image_dir' => '/....' }
# output to StdOut
sheet.apply( xml_doc )
# output to 'str'
str = ""
sheet.output = [ str ]
246
Ruby
sheet.apply( xml_doc )
Further Reading
247
Ruby
What is SOAP?
The Simple Object Access Protocol (SOAP), is a cross-platform and languageindependent RPC protocol based on XML and, usually (but not necessarily) HTTP.
It uses XML to encode the information that makes the remote procedure call,
and HTTP to transport that information across a network from clients to servers
and vice versa.
SOAP has several advantages over other technologies like COM, CORBA etc: for
example, its relatively cheap deployment and debugging costs, its extensibility
and ease-of-use, and the existence of several implementations for different
languages and platforms.
Please refer to our simple tutorial SOAP to understand it in detail.
This chapter makes you familiar with the SOAP implementation for Ruby
(SOAP4R). This is a basic tutorial, so if you need a deep detail, you would need
to refer other resources.
Installing SOAP4R
SOAP4R is the SOAP implementation for Ruby developed by Hiroshi Nakamura
and can be downloaded from:
NOTE: There may be a great chance that you already have installed this
component.
Download SOAP
If you are aware of gem utility then you can use the following command to
install SOAP4R and related packages.
$ gem install soap4r --include-dependencies
If you are working on Windows, then you need to download a zipped file from
the above location and need to install it using the standard installation method
by running ruby install.rb.
248
Ruby
Standalone (SOAP::RPC:StandaloneServer)
This chapter gives detail on writing a stand alone server. The following steps are
involved in writing a SOAP server.
# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end
249
Ruby
Description
receiver
methodName
paramArg
Ruby
%w(inout inoutParam),
%w(out outParam),
%w(retval return)
])
myServer.start
Here is the description of required parameters :
Paramter
Description
ServerName
urn:ruby:ServiceName
hostname
port
Example
Now, using the above steps, let us write one standalone server:
require "soap/rpc/standaloneserver"
begin
class MyServer < SOAP::RPC::StandaloneServer
251
Ruby
# Handler methods
def add(a, b)
return a + b
end
def div(a, b)
return a / b
end
end
server = MyServer.new("MyServer",
'urn:ruby:calculation', 'localhost', 8080)
trap('INT){
server.shutdown
}
server.start
rescue => err
puts err.message
end
When executed, this server application starts a standalone SOAP server on
localhost and listens for requests on port 8080. It exposes one service methods,
add and div, which takes two parameters and return the result.
Now, you can run this server in background as follows:
$ ruby MyServer.rb&
Ruby
Following is the bare minimum information you would need to call a SOAP
service:
Now, we will write a SOAP client which would call service methods defined in
above example, named add and div.
Here are the main steps to create a SOAP client.
Description
endPoint
nameSpace
soapAction
A value for the SOAPAction field of the HTTP header. If nil this
defaults to the empty string "".
for
all
RPCs
done
with
this
Description
The name of the remote web service method.
253
Ruby
paramArg
Example
Based on the above steps, we will write a SOAP client as follows:
#!/usr/bin/ruby -w
require 'soap/rpc/driver'
NAMESPACE = 'urn:ruby:calculation'
URL = 'http://localhost:8080/'
begin
driver = SOAP::RPC::Driver.new(URL, NAMESPACE)
29. TK GUIDE
Ruby
Introduction
The standard graphical user interface (GUI) for Ruby is Tk. Tk started out as the
GUI for the Tcl scripting language developed by John Ousterhout.
Tk has the unique distinction of being the only cross-platform GUI. Tk runs on
Windows, Mac, and Linux and provides a native look-and-feel on each operating
system.
The basic component of a Tk-based application is called a widget. A component
is also sometimes called a window, since, in Tk, "window" and "widget" are often
used interchangeably.
Tk applications follow a widget hierarchy where any number of widgets may be
placed within another widget, and those widgets within another widget, ad
infinitum. The main widget in a Tk program is referred to as the root widget and
can be created by making a new instance of the TkRoot class.
Most Tk-based applications follow the same cycle: create the widgets,
place them in the interface, and finally, bind the events associated with
each widget to a method.
There are three geometry managers; place, grid and pack that are
responsible for controlling the size and location of each of the widgets in
the interface.
Installation
The Ruby Tk bindings are distributed with Ruby but Tk is a separate installation.
Windows users can download a single click Tk installation from ActiveState's
ActiveTcl.
Mac and Linux users may not need to install it because there is a great chance
that its already installed along with OS but if not, you can download prebuilt
packages or get the source from the Tcl Developer Xchange.
Simple Tk Application
A typical structure for Ruby/Tk programs is to create the main or root window
(an instance of TkRoot), add widgets to it to build up the user interface, and
then start the main event loop by calling Tk.mainloop.
The traditional Hello, World! example for Ruby/Tk looks something like this:
255
Ruby
require 'tk'
Ruby
TkFrame
Description
A frame is a widget that displays just as a simple rectangle. Frames are primarily
used as a container for other widgets, which are under the control of a geometry
manager such as grid.
The only features of a frame are its background color and an optional 3-D border
to make the frame appear raised or sunken.
Syntax
Here is a simple syntax to create a Frame Widget:
TkFrame.new {
.....Standard Options....
.....Widget-specific Options....
}
257
Ruby
Standard Options
borderwidth
highlightbackground
highlightthickness
takefocus
highlightcolor
relief
cursor
Widget-Specific Options
SN
1
258
Ruby
Event Bindings
When a new frame is created, it has no default event bindings: frames are not
intended to be interactive.
Examples
require "tk"
f1 = TkFrame.new {
relief 'sunken'
borderwidth 3
background "red"
padx 15
pady 20
pack('side' => 'left')
}
f2 = TkFrame.new {
relief 'groove'
borderwidth 1
background "yellow"
padx 10
pady 10
pack('side' => 'right')
}
TkButton.new(f1) {
text 'Button1'
command {print "push button1!!\n"}
pack('fill' => 'x')
259
Ruby
}
TkButton.new(f1) {
text 'Button2'
command {print "push button2!!\n"}
pack('fill' => 'x')
}
TkButton.new(f2) {
text 'Quit'
command 'exit'
pack('fill' => 'x')
}
Tk.mainloop
This will produce the following result:
TkButton
Description
A button is very much designed for the user to interact with, and in particular,
press to perform some action. A button is a widget that displays a textual string,
bitmap or image. If text is displayed, it must all be in a single font, but it can
occupy multiple lines on the screen.
A button can display itself in either of three different ways, according to the state
option. It can be made to appear raised, sunken, or flat and it can be made to
flash.
260
Ruby
Syntax
Here is a simple syntax to create this widget:
TkButton.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
activeforeground
anchor
background
bitmap
borderwidth
cursor
disabledforeground
font
foreground
highlightbackground
highlightcolor
highlightthickness
image
justify
padx
pady
relief
repeatdelay
repeatinterval
takefocus
text
261
Ruby
textvariable
underline
wraplength
Widget-Specific Options
SN
1
262
Ruby
Event Bindings
Ruby/Tk automatically creates class bindings for buttons that give them the
following default behavior:
If mouse button 1 is pressed over a button and later released over the
button, the button is invoked. However, if the mouse is not over the
button when button 1 is released, then no invocation occurs.
When a button has the input focus, the space key causes the button to be
invoked.
If the button's state is disabled then none of the above actions occur: the button
is completely non-responsive.
Examples
require 'tk'
def myproc
puts "The user says OK."
exit
end
root = TkRoot.new
btn_OK = TkButton.new(root) do
text "OK"
borderwidth 5
underline 0
state "normal"
cursor "watch"
font TkFont.new('times 20 bold')
foreground
"red"
activebackground "blue"
relief
"groove"
263
Ruby
end
Tk.mainloop
This will produce the following result if you will click over this button then ruby
method myproc would be executed.
TkLabel
Description
A label is a widget that displays text or images, typically that the user will just
view but not otherwise interact with. Labels are used for such things as
identifying controls or other parts of the user interface, providing textual
feedback or results, etc.
A label can display a textual string, bitmap or image. If text is displayed, it must
all be in a single font, but it can occupy multiple lines on the screen (if it
contains newlines or if wrapping occurs because of the wraplength option) and
one of the characters may optionally be underlined using the underline option.
Syntax
Here is a simple syntax to create this widget:
TkLabel.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
anchor
264
Ruby
background
bitmap
borderwidth
cursor
font
foreground
highlightbackground
highlightcolor
highlightthickness
image
justify
padx
pady
relief
takefocus
text
textvariable
underline
wraplength
Widget-Specific Options
SN
1
265
Ruby
Event Bindings
When a new label is created, it has no default event bindings: labels are not
intended to be interactive.
Examples
require 'tk'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
Lbl = TkLabel.new(root) do
textvariable
borderwidth 5
font TkFont.new('times 20 bold')
foreground
"red"
relief
"groove"
end
Lbl['textvariable'] = $resultsVar
$resultsVar.value = 'New value to display'
Tk.mainloop
This will produce the following result:
266
Ruby
TkEntry
Description
A Entry presents the user with a single-line text field that they can use to type
in a value. These can be just about anything: their name, a city, a password,
social security number, and so on.
Syntax
Here is a simple syntax to create this widget:
TkEntry.new{
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
background
borderwidth
cursor
exportselection
font
foreground
highlightbackground
highlightcolor
highlightthickness
justify
relief
selectbackground
selectborderwidth
selectforeground
takefocus
textvariable
267
Ruby
xscrollcommand
Widget-Specific Options
SN
Specifies the background color to use when the entry is disabled. If this
option is the empty string, the normal background color is used.
disabledforeground => String
Specifies the foreground color to use when the entry is disabled. If this
option is the empty string, the normal foreground color is used.
readonlybackground => String
Specifies the background color to use when the entry is read-only. If this
option is the empty string, the normal background color is used.
show => String
If this option is specified, then the true contents of the entry are not
displayed in the window. Instead, each character in the entry's value will
be displayed as the first character in the value of this option, such as ``*''.
This is useful, for example, if the entry is to be used to enter a password.
If characters in the entry are selected and copied elsewhere, the
information copied will be what is displayed, not the true contents of the
entry.
state => String
Ruby
validation, you must explicitly state which mode you wish to use.
validatecommand => String
7
Specifies a script to eval when you want to validate the input into the entry
widget.
width => Integer
Specifies an integer value indicating the desired width of the entry window,
in average-size characters of the widget's font. If the value is less than or
equal to zero, the widget picks a size just large enough to hold its current
text.
Validation of Entry
We can validate the entered value by setting the validatecommand option to a
callback, which will be evaluated according to the validate option as follows:
Manipulating Entries
The following useful methods are available to manipulate the content of an
entry:
Ruby
Event Bindings
Ruby/Tk automatically creates class bindings for entries that give them the
following default behavior:
Clicking mouse button 1 positions the insertion cursor just before the
character underneath the mouse cursor, sets the input focus to this
widget, and clears any selection in the widget. Dragging with mouse
button 1 strokes out a selection between the insertion cursor and the
character under the mouse.
Double-clicking with mouse button 1 selects the word under the mouse
and positions the insertion cursor at the beginning of the word. Dragging
after a double click will stroke out a selection consisting of whole words.
Triple-clicking with mouse button 1 selects all of the text in the entry and
positions the insertion cursor before the first character.
The ends of the selection can be adjusted by dragging with mouse button
1 while the Shift key is down; this will adjust the end of the selection that
was nearest to the mouse cursor when button 1 was pressed. If the
button is double-clicked before dragging then the selection will be
adjusted in units of whole words.
Clicking mouse button 1 with the Control key down will position the
insertion cursor in the entry without affecting the selection.
If any normal printing characters are typed in an entry, they are inserted
at the point of the insertion cursor.
The view in the entry can be adjusted by dragging with mouse button 2. If
mouse button 2 is clicked without moving the mouse, the selection is
copied into the entry at the position of the insertion cursor.
If the mouse is dragged out of the entry on the left or right sides while
button 1 is pressed, the entry will automatically scroll to make more text
visible (if there is more text off-screen on the side where the mouse left
the window).
The Left and Right keys move the insertion cursor one character to the
left or right; they also clear any selection in the entry and set the
selection anchor. If Left or Right is typed with the Shift key down, then
the insertion cursor moves and the selection is extended to include the
new character. Control-Left and Control-Right move the insertion cursor
by words, and Control-Shift-Left and Control-Shift-Right move the
270
Ruby
insertion cursor by words and also extend the selection. Control-b and
Control-f behave the same as Left and Right, respectively. Meta-b and
Meta-f behave the same as Control-Left and Control-Right, respectively.
The Home key, or Control-a, will move the insertion cursor to the
beginning of the entry and clear any selection in the entry. Shift-Home
moves the insertion cursor to the beginning of the entry and also extends
the selection to that point.
The End key, or Control-e, will move the insertion cursor to the end of the
entry and clear any selection in the entry. Shift-End moves the cursor to
the end and extends the selection to that point.
The Select key and Control-Space set the selection anchor to the position
of the insertion cursor. They don't affect the current selection. Shift-Select
and Control-Shift-Space adjust the selection to the current position of the
insertion cursor, selecting from the anchor to the insertion cursor if there
was not any selection previously.
The F16 key (labelled Copy on many Sun workstations) or Meta-w copies
the selection in the widget to the clipboard, if there is a selection.
The F20 key (labelled Cut on many Sun workstations) or Control-w copies
the selection in the widget to the clipboard and deletes the selection. If
there is no selection in the widget then these keys have no effect.
The Delete key deletes the selection, if there is one in the entry. If there
is no selection, it deletes the character to the right of the insertion cursor.
The BackSpace key and Control-h delete the selection, if there is one in
the entry. If there is no selection, it deletes the character to the left of the
insertion cursor.
Control-k deletes all the characters to the right of the insertion cursor.
Control-t reverses the order of the two characters to the right of the
insertion cursor.
271
Ruby
If the entry is disabled using the state option, then the entry's view can still be
adjusted and text in the entry can still be selected, but no insertion cursor will
be displayed and no text modifications will take place.
Examples
require 'tk'
root = TkRoot.new
root.title = "Window"
entry1 = TkEntry.new(root)
entry2 = TkEntry.new(root) do
show '*'
end
variable1 = TkVariable.new
variable2 = TkVariable.new
entry1.textvariable = variable1
entry2.textvariable = variable2
variable1.value = "Enter any text value"
variable2.value = "Enter any confidential value"
=> 150,
'x'
=> 10,
'y'
=> 10)
=> 150,
'x'
=> 10,
'y'
=> 40)
Tk.mainloop
272
Ruby
TkCheckButton
Description
A Checkbutton is like a regular button, except that not only can the user press
it, which will invoke a command callback, but it also holds a binary value of
some kind (i.e., a toggle). Checkbuttons are used all the time when a user is
asked to choose between, e.g., two different values for an option.
A checkbutton can display a textual string, bitmap or image. If text is displayed,
it must all be in a single font, but it can occupy multiple lines on the screen (if it
contains newlines or if wrapping occurs because of the wraplength option) and
one of the characters may optionally be underlined using the underline option.
A checkbutton has all of the behavior of a simple button, including the following:
it can display itself in either of three different ways, according to the state
option; it can be made to appear raised, sunken, or flat; it can be made to flash;
and it invokes a Tcl command whenever mouse button 1 is clicked over the
checkbutton.
Syntax
Here is a simple syntax to create this widget:
TkCheckButton.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
activeforeground
anchor
273
Ruby
background
bitmap
borderwidth
compound
cursor
disabledforeground
font
foreground
highlightbackground
highlightcolor
highlightthickness
image
justify
padx
pady
relief
takefocus
text
textvariable
underline
wraplength
Widget-Specific Options
SN
1
Ruby
Ruby
Specifies one of three states for the button: normal, active, or disabled.
In normal state the button is displayed using the foreground and
background options. The active state is typically used when the pointer is
over the button. In active state the button is displayed using the
activeforeground and activebackground options. Disabled state means
that the button should be insensitive.
9
10
Event Bindings
Ruby/Tk automatically creates class bindings for checkbuttons that give them
the following default behavior:
When a checkbutton has the input focus, the space key causes the
checkbutton to be invoked.
If the checkbutton's state is disabled then none of the above actions occur: the
checkbutton is completely non-responsive.
Examples
require 'tk'
root = TkRoot.new
root.title = "Window"
CkhButton1 = TkCheckButton.new(root) do
text "Orange"
276
Ruby
indicatoron "true"
background
"red"
relief "groove"
height 2
width 2
onvalue 'Orange'
place('height' => 25,'width'
command (select)
end
CkhButton2 = TkCheckButton.new(root) do
text "Banana"
background
"red"
relief "groove"
height 2
width 2
onvalue 'Banana'
place('height' => 25,'width' => 100, 'x' => 10, 'y'=> 40)
end
Tk.mainloop
This will produce the following result:
TkRadioButton
Description
A radiobutton lets you choose between one of a number of mutually exclusive
choices, unlike a checkbutton, it is not limited to just two choices. Radiobuttons
are always used together in a set and are good when the number of choices is
fairly small.
277
Ruby
Syntax
Here is a simple syntax to create this widget:
TkRadiobutton.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
activeforeground
anchor
background
bitmap
borderwidth
compound
cursor
disabledforeground
font
foreground
highlightbackground
highlightcolor
highlightthickness
278
Ruby
image
justify
padx
pady
relief
takefocus
text
textvariable
underline
wraplength
Widget-Specific Options
SN
1
Ruby
boolean value. If false, the relief option is ignored and the widget's relief
is always sunken if the widget is selected and raised otherwise.
4
10
280
Ruby
Event Bindings
Ruby/Tk automatically creates class bindings for Radiobutton that gives them
the following default behavior:
When a radiobutton has the input focus, the space key causes the
checkbutton to be invoked.
If the radiobutton's state is disabled then none of the above actions occur: the
radiobutton is completely non-responsive.
Examples
require "tk"
def print_v
print $v, "\n"
end
$v = TkVariable.new
TkRadioButton.new {
text 'top'
variable $v
value 'top'
anchor 'w'
pack('side' => 'top', 'fill' => 'x')
}
TkRadioButton.new {
text 'middle'
variable $v
value 'middle'
anchor 'w'
pack('side' => 'top', 'fill' => 'x')
281
Ruby
}
TkRadioButton.new {
text 'bottom'
variable $v
value 'bottom'
anchor 'w'
pack('side' => 'top', 'fill' => 'x')
}
TkButton.new {
text 'Quit'
command 'exit'
pack
}
Tk.mainloop
This will produce the following result:
TkListbox
Description
A radiobutton displays a list of single-line text items, usually lengthy, and
allows the user to browse through the list, selecting one or more.
When first created, a new listbox has no elements. Elements may be added or
deleted using provided methods. In addition, one or more elements may be
selected from the listed items.
282
Ruby
It is not necessary for all the elements to be displayed in the listbox window at
once. Listboxes allow scrolling in both directions using the standard
xscrollcommand and yscrollcommand options.
Syntax
Here is a simple syntax to create this widget:
TkListbox.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
background
borderwidth
cursor
disabledforeground
exportselection
font
foreground
hight
highlightbackground
highlightcolor
highlightthickness
offset
relief
selectbackground
selectborderwidth
selectforeground
setgrid
takefocus
tile
283
Ruby
width
xscrollcommand
yscrollcommand
Widget-Specific Options
SN
1
Ruby
The listvariable: variable allows you to link a variable (which must hold a
list) to the listbox. Each element of this list is a string representing one
item in the listbox. So to add, remove, or rearrange items in the listbox,
you can simply manipulate this variable as you would any other list.
The insert idx item ?item... ? method is used to add one or more items
to the list; "idx" is a 0-based index indicating the position of the item
before which the item(s) should be added; specify "end" to put the new
items at the end of the list.
The delete first ?last? method is used to delete one or more items from
the list; "first" and "last" are indices as per the "insert" method.
The get first ?last? method returns the contents of a single item at the
given position, or a list of the items between "first" and "last".
The curselection method is used to find out which item or items in the
listbox the user has currently selected. This will return the list of indices of
all items currently selected; this may be an empty list.
The selection set first ?last? method is used to select an item, or all
items in a range.
Indices
Many of the methods for listboxes take one or more indices as arguments. An
index specifies a particular element of the listbox, in any of the following ways:
285
Ruby
active: Indicates the element that has the location cursor. This element
will be displayed with an underline when the listbox has the keyboard
focus, and it is specified with the activate method.
anchor: Indicates the anchor point for the selection, which is set with the
selection anchor method.
end: Indicates the end of the listbox. For some commands this means just
after the last element; for other commands it means the last element.
Event Bindings
Ruby/Tk creates class bindings for listboxes that give them Motif-like behavior.
Much of the behavior of a listbox is determined by its selectmode option, which
selects one of four ways of dealing with the selection.
Most people will probably want to use the browse mode for single selections and
the extended mode for multiple selections; the other modes appear to be useful
only in special situations.
In addition to the above behavior, there are many other additional behaviors
associated with a listbox, which are not covered in this tutorial:
Example 1
require "tk"
root = TkRoot.new
root.title = "Window"
list = TkListbox.new(root) do
286
Ruby
width 20
height 10
setgrid 1
selectmode 'multiple'
pack('fill' => 'x')
end
Tk.mainloop
This will produce the following result:
Example 2
Following is the example using listvariable option to populate list items:
require "tk"
root = TkRoot.new
root.title = "Window"
287
Ruby
list = TkListbox.new(root) do
width 20
height 10
setgrid 1
listvariable $colornames
pack('fill' => 'x')
end
Tk.mainloop
This will produce the following result:
Example 3
Following example explains how to use TkScrollbar widget along with list box.
require "tk"
root = TkRoot.new
root.title = "Window"
list = TkListbox.new(root) do
288
Ruby
listvariable $colornames
pack('fill' => 'x')
end
=> 100,
'x'
=> 10,
'y'
=> 10)
scroll = TkScrollbar.new(root) do
orient 'vertical'
place('height' => 150, 'x' => 110)
end
list.yscrollcommand(proc { |*args|
scroll.set(*args)
})
scroll.command(proc { |*args|
list.yview(*args)
})
Tk.mainloop
289
Ruby
TkComboBox
Description
A Combobox combines an entry with a list of choices available to the user. This
lets them either choose from a set of values you've provided (e.g., typical
settings), but also put in their own value.
Syntax
Here is a simple syntax to create this widget:
Tk::BWidget::ComboBox.new(root){
.....Options....
}
Options
Combobox combines the options related to TkEntry and TkListbox widgets.
Event Bindings
Combobox inherits event bindings from TkEntry and TkListbox widgets.
Examples
require 'tk'
require 'tkextlib/bwidget'
root = TkRoot.new
root.title = "Window"
290
Ruby
combobox = Tk::BWidget::ComboBox.new(root)
combobox.values = [1, 2, 3, 4]
combobox.place('height' => 25,
'width'
=> 100,
'x'
=> 10,
'y'
=> 10)
Tk.mainloop
This will produce the following result:
TkMenu
Description
A menu is a widget that displays a collection of one-line entries arranged in one
or more columns. There exist several different types of entries, each with
different properties. Entries of different types may be combined in a single
menu. Menu entries are not the same as entry widgets. In fact, menu entries are
not even distinct widgets; the entire menu is one widget.
When first created, a new listbox has no elements. Elements may be added or
deleted using provided methods. In addition, one or more elements may be
selected from the listed items.
It is not necessary for all the elements to be displayed in the listbox window at
once. Listboxes allow scrolling in both directions using the standard
xscrollcommand and yscrollcommand options.
291
Ruby
Syntax
Here is a simple syntax to create this widget:
TkMenu.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
background
disabledforeground
relief
activeborderwidth
borderwidth
font
takefocus
activeforeground
cursor
foreground
Widget-Specific Options
SN
1
Ruby
293
Ruby
The type(index) method returns the type of the menu entry given by
index. This is the type argument passed to the add widget method when
the entry was created, such as command or separator, or tearoff for a
tear-off entry.
The yposition(index) method returns a decimal string giving the ycoordinate within the menu window of the topmost pixel in the entry
specified by index.
Menu Configuration
The default bindings support four different ways of using menus:
Pulldown Menus: This is the most common case. You create one
menubutton widget for each top-level menu, and typically you arrange a
series of menubuttons in a row in a menubar window. You also create the
top-level menus and any cascaded submenus, and tie them together with
menu options in menubuttons and cascade menu entries.
Ruby
Event Bindings
Ruby/Tk automatically creates class bindings for menus that give them the
following default behavior:
When the mouse enters a menu, the entry underneath the mouse cursor
activates; as the mouse moves around the menu, the active entry
changes to track the mouse.
When the mouse leaves a menu all of the entries in the menu deactivate,
except in the special case where the mouse moves from a menu to a
cascaded submenu.
When a button is released over a menu, the active entry (if any) is
invoked. The menu also unposts unless it is a torn-off menu.
The Space and Return keys invoke the active entry and unpost the menu.
The Escape key aborts a menu selection in progress without invoking any
entry. It also unposts the menu unless it is a torn-off menu.
The Up and Down keys activate the next higher or lower entry in the
menu. When one end of the menu is reached, the active entry wraps
around to the other end.
The Left key moves to the next menu to the left. If the current menu is a
cascaded submenu, then the submenu is unposted and the current menu
entry becomes the cascade entry in the parent. If the current menu is a
top-level menu posted from a menubutton, then the current menubutton
is unposted and the next menubutton to the left is posted. Otherwise the
key has no effect. The left-right order of menubuttons is determined by
their stacking order: Tk assumes that the lowest menubutton (which by
default is the first one created) is on the left.
295
Ruby
The Right key moves to the next menu to the right. If the current entry is
a cascade entry, then the submenu is posted and the current menu entry
becomes the first entry in the submenu. Otherwise, if the current menu
was posted from a menubutton, then the current menubutton is unposted
and the next menubutton to the right is posted.
Disabled menu entries are non-responsive. They don't activate and ignore the
mouse button presses and releases.
Examples
require "tk"
root = TkRoot.new
root.title = "Window"
menu_click = Proc.new {
Tk.messageBox(
'type'
=> "ok",
'icon'
=> "info",
'title'
=> "Title",
file_menu = TkMenu.new(root)
file_menu.add('command',
'label'
=> "New...",
'command'
=> menu_click,
'underline' => 0)
file_menu.add('command',
'label'
=> "Open...",
'command'
=> menu_click,
'underline' => 0)
file_menu.add('command',
296
Ruby
'label'
=> "Close",
'command'
=> menu_click,
'underline' => 0)
file_menu.add('separator')
file_menu.add('command',
'label'
=> "Save",
'command'
=> menu_click,
'underline' => 0)
file_menu.add('command',
'label'
'command'
=> menu_click,
'underline' => 5)
file_menu.add('separator')
file_menu.add('command',
'label'
=> "Exit",
'command'
=> menu_click,
'underline' => 3)
menu_bar = TkMenu.new
menu_bar.add('cascade',
'menu'
=> file_menu,
root.menu(menu_bar)
Tk.mainloop
297
Ruby
TkMenubutton
Description
A menubutton is a widget that displays a textual string, bitmap, or image and is
associated with a menu widget. If text is displayed, it must all be in a single
font, but it can occupy multiple lines on the screen (if it contains newlines or if
wrapping occurs because of the wraplength option) and one of the characters
may optionally be underlined using the underline option.
In normal usage, pressing mouse button 1 over the menubutton causes the
associated menu to be posted just underneath the menubutton. If the mouse is
moved over the menu before releasing the mouse button, the button release
causes the underlying menu entry to be invoked. When the button is released,
the menu is unposted.
Menubuttons are typically organized into groups called menu bars that allow
scanning: if the mouse button is pressed over one menubutton and the mouse is
moved over another menubutton in the same menu bar without releasing the
mouse button, then the menu of the first menubutton is unposted and the menu
of the new menubutton is posted instead.
Syntax
Here is a simple syntax to create this widget:
TkMenubutton.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
298
Ruby
Standard Options
activebackground
cursor
highlightthickness
takefocus
activeforeground
disabledforeground
image
text
anchor
font
justify
textvariable
background
foreground
padx
underline
bitmap
highlightbackground
pady
wraplength
borderwidth
highlightcolor
relief
Widget-Specific Options
SN
1
Ruby
Specifies whether the button should display both an image and text, and
if so, where the image should be placed relative to the text. Valid values
for this option are bottom, center, left, none, right and top. The default
value is none, meaning that the button will display either an image or
text, depending on the values of the image and bitmap options.
2
Event Bindings
Ruby/Tk automatically creates class bindings for menubuttons that give them
the following default behavior:
300
Ruby
When a menubutton is posted, its associated menu claims the input focus
to allow keyboard traversal of the menu and its submenus.
If the underline option has been specified for a menubutton then keyboard
traversal may be used to post the menubutton: Alt+x, where x is the
underlined character (or its lower-case or upper-case equivalent), may be
typed in any window under the menubutton's toplevel to post the
menubutton.
The F10 key may be typed in any window to post the first menubutton
under its toplevel window that isn't disabled.
If a menubutton has the input focus, the space and return keys post the
menubutton.
If the menubutton's state is disabled then none of the above actions occur: the
menubutton is completely non-responsive.
Examples
require "tk"
mbar = TkFrame.new {
relief 'raised'
borderwidth 2
}
301
Ruby
TkMenubutton.new(mbar) {|mb|
text "File"
underline 0
menu TkMenu.new(mb) {
add 'command', 'label' => 'New...', 'underline' => 0,
'command' => proc {print "opening new file\n"}
add 'command', 'label' => 'Quit',
'underline' => 0, 'command' => proc{exit}
}
pack('side' => 'left', 'padx' => '1m')
}
TkMenubutton.new(mbar) {|mb|
text "Help"
underline 0
menu TkMenu.new(mb) {
add 'command', 'label' => 'About', 'underline' => 0,
'command' => proc {print "This is menu example.\n"}
}
pack('side' => 'left', 'padx' => '1m')
}
Tk.mainloop
This will produce the following result:
302
Ruby
Tk.messageBox
Standard Options
NA
Widget-Specific Options
SN
1
303
Ruby
Event Bindings
NA
Examples
require 'tk'
root = TkRoot.new
root.title = "Window"
msgBox = Tk.messageBox(
'type'
=> "ok",
'icon'
=> "info",
'title'
TkScrollbar
Description
A Scrollbar helps the user to see all parts of another widget, whose content is
typically much larger than what can be shown in the available screen space.
304
Ruby
A scrollbar displays two arrows, one at each end of the scrollbar, and a slider in
the middle portion of the scrollbar. The position and size of the slider indicate
which portion of the document is visible in the associated window.
Syntax
Here is a simple syntax to create this widget:
TkScrollbar.new{
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
highlightbackground
orient
takefocus
background
highlightcolor
relief
troughcolor
borderwidth
highlightthickness
repeatdelay
cursor
jump
repeatinterval
305
Ruby
Widget-Specific Options
SN
1
Elements of Scrollbar
A scrollbar displays five elements, which are referred in the methods for the
scrollbar:
Manipulating Scrollbar
The following useful methods to manipulate the content of a scrollbar:
306
Ruby
get:Returns the scrollbar settings in the form of a list whose elements are
the arguments to the most recent set method.
identify(x, y): Returns the name of the element under the point given by
x and y (such as arrow1), or an empty string if the point does not lie in
any element of the scrollbar. X and y must be pixel coordinates relative to
the scrollbar widget.
Event Bindings
Ruby/Tk automatically creates class bindings for scrollbars that gives them the
following default behavior. If the behavior is different for vertical and horizontal
scrollbars, the horizontal behavior is described in parentheses:
Pressing button 1 over arrow1 causes the view in the associated widget to
shift up (left) by one unit so that the document appears to move down
(right) one unit. If the button is held down, the action auto-repeats.
Pressing button 1 over trough1 causes the view in the associated widget
to shift up (left) by one screenful so that the document appears to move
down (right) one screenful. If the button is held down, the action autorepeats.
Pressing button 1 over the slider and dragging causes the view to drag
with the slider. If the jump option is true, then the view doesn't drag
along with the slider; it changes only when the mouse button is released.
Pressing button 1 over trough2 causes the view in the associated widget
to shift down (right) by one screenful so that the document appears to
307
Ruby
move up (left) one screenful. If the button is held down, the action autorepeats.
Pressing button 1 over arrow2 causes the view in the associated widget to
shift down (right) by one unit so that the document appears to move up
(left) one unit. If the button is held down, the action auto-repeats.
If button 2 is pressed over the trough or the slider, it sets the view to
correspond to the mouse position; dragging the mouse with button 2
down causes the view to drag with the mouse. If button 2 is pressed over
one of the arrows, it causes the same behavior as pressing button 1.
If button 1 is pressed with the Control key down, then if the mouse is over
arrow1 or trough1 the view changes to the very top (left) of the
document; if the mouse is over arrow2 or trough2 the view changes to
the very bottom (right) of the document; if the mouse is anywhere else
then the button press has no effect.
In vertical scrollbars the Up and Down keys have the same behavior as
mouse clicks over arrow1 and arrow2, respectively. In horizontal
scrollbars these keys have no effect.
In horizontal scrollbars the Up and Down keys have the same behavior as
mouse clicks over arrow1 and arrow2, respectively. In vertical scrollbars
these keys have no effect.
The Prior and Next keys have the same behavior as mouse clicks over
trough1 and trough2, respectively.
The Home key adjusts the view to the top (left edge) of the document.
The End key adjusts the view to the bottom (right edge) of the document.
Examples
require "tk"
list = TkListbox.new {
yscroll proc{|idx|
308
Ruby
scroll.set *idx
}
width 20
height 16
setgrid 1
pack('side' => 'left', 'fill' => 'y', 'expand' => 1)
}
scroll = TkScrollbar.new {
command proc{|idx|
list.yview *idx
}
pack('side' => 'left', 'fill' => 'y', 'expand' => 1)
}
for f in Dir.glob("*")
list.insert 'end', f
end
Tk.mainloop
This will produce the following result:
309
Ruby
TkCanvas
Description
A Canvas widget implements structured graphics. A canvas displays any number
of items, which may be things like rectangles, circles, lines, and text.
Items may be manipulated (e.g., moved or re-colored) and callbacks may be
associated with items in much the same way that the bind method allows
callbacks to be bound to widgets.
Syntax
Here is a simple syntax to create this widget:
TkCanvas.new{
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
background
borderwidth
cursor
highlightbackground
highlightcolor
highlightthickness
relief
selectbackground
selectborderwidth
selectforeground
state
takefocus
tile
xscrollcommand
yscrollcommand
310
Ruby
Widget-Specific Options
SN
1
confine =>Boolean
Specifies a boolean value that indicates whether or not it should be
allowable to set the canvas's view outside the region defined by the
scrollregion argument. Defaults to true, which means that the view will be
constrained within the scroll region.
height =>Integer
Specifies a desired window height that the canvas widget should request
from its geometry manager.
scrollregion =>Coordinates
Specifies a list with four coordinates describing the left, top, right, and
bottom coordinates of a rectangular region. This region is used for
scrolling purposes and is considered to be the boundary of the
information in the canvas.
state =>String
Modifies the default state of the canvas where state may be set to one of:
normal, disabled, or hidden. Individual canvas objects all have their
own state option, which overrides the default state.
width =>Integer
Specifies a desired window width that the canvas widget should request
from its geometry manager.
xscrollincrement =>Integer
Specifies an increment for horizontal scrolling, in any of the usual forms
311
Ruby
permitted for screen distances. If the value of this option is greater than
zero, the horizontal view in the window will be constrained so that the
canvas x coordinate at the left edge of the window is always an even
multiple of xscrollincrement; furthermore, the units for scrolling will also
be xscrollincrement.
8
yscrollincrement =>Integer
Specifies an increment for vertical scrolling, in any of the usual forms
permitted for screen distances. If the value of this option is greater than
zero, the vertical view in the window will be constrained so that the
canvas y coordinate at the top edge of the window is always an even
multiple of yscrollincrement; furthermore, the units for scrolling will also
be yscrollincrement.
Indices
Indices are used for methods such as inserting text, deleting a range of
characters, and setting the insertion cursor position. An index may be specified
in any of a number of ways, and different types of items may support different
forms for specifying indices.
Text items support the following forms for an index:
end: Refers to the character or coordinate just after the last one in the
item (same as the number of characters or coordinates in the item).
insert: Refers to the character just before which the insertion cursor is
drawn in this item. Not valid for lines and polygons.
Creating Items
When you create a new canvas widget, it will essentially be a large rectangle
with nothing on it; truly a blank canvas in other words. To do anything useful
with it, you'll need to add items to it.
There are a wide variety of different types of items you can add. Following
methods will be used to create different items inside a canvas:
312
Ruby
Arc Items
Items of type arc appear on the display as arc-shaped regions. An arc is a
section of an oval delimited by two angles. Arcs are created with methods of the
following form:
The TkcArc.new(canvas, x1, y1, x2, y2, ?option, value, option, value, ...?)
method will be used to create an arc.
The arguments x1, y1, x2, and y2 give the coordinates of two diagonally
opposite corners of a rectangular region enclosing the oval that defines the arc.
Here is the description of other options:
extent => degrees: Specifies the size of the angular range occupied by
the arc. If it is greater than 360 or less than -360, then degrees modulo
360 is used as the extent.
fill => color: Fills the region of the arc with color.
outline => color: Color specifies a color to use for drawing the arc's
outline.
start => degrees: Specifies the beginning of the angular range occupied
by the arc.
style => type: Specifies how to draw the arc. If type is pieslice (the
default) then the arc's region is defined by a section of the oval's
perimeter plus two line segments, one between the center of the oval and
each end of the perimeter section. If type is chord then the arc's region is
defined by a section of the oval's perimeter plus a single line segment
connecting the two end points of the perimeter section. If type is arc then
the arc's region consists of a section of the perimeter alone.
tags => tagList: Specifies a set of tags to apply to the item. TagList
consists of a list of tag names, which replace any existing tags for the
item. TagList may be an empty list.
Bitmap Items
Items of type bitmap appear on the display as images with two colors,
foreground and background. Bitmaps are created with methods of the following
form:
The TkcBitmap.new(canvas, x, y, ?option, value, option, value, ...?)
method will be used to create a bitmap.
The arguments x and y specify the coordinates of a point used to position the
bitmap on the display. Here is the description of other options:
313
Ruby
background => color: Specifies a color to use for each of the bitmap
pixels whose value is 0.
foreground => color: Specifies a color to use for each of the bitmap
pixels whose value is 1.
tags => tagList: Specifies a set of tags to apply to the item. TagList
consists of a list of tag names, which replace any existing tags for the
item. TagList may be an empty list.
Image Items
Items of type image are used to display images on a canvas. Images are created
with methods of the following form: :
The TkcImage.new(canvas,x, y, ?option, value, option, value, ...?) method
will be used to create an image.
The arguments x and y specify the coordinates of a point used to position the
image on the display. Here is the description of other options:
image => name: Specifies the name of the image to display in the item.
This image must have been created previously with the image create
command.
tags => tagList: Specifies a set of tags to apply to the item. TagList
consists of a list of tag names, which replace any existing tags for the
item. TagList may be an empty list.
Line items
Items of type line appear on the display as one or more connected line segments
or curves. Lines are created with methods of the following form:
The TkcLine.new(canvas, x1, y1..., xn, yn, ?option, value, ...?) method will
be used to create a line.
314
Ruby
The arguments x1 through yn give the coordinates for a series of two or more
points that describe a series of connected line segments. Here is the description
of other options:
capstyle => style: Specifies the ways in which caps are to be drawn at
the endpoints of the line. Possible values are butt, projecting, or round.
fill => color: Color specifies a color to use for drawing the line.
joinstyle => style: Specifies the ways in which joints are to be drawn at
the vertices of the line. Possible values are bevel, miter, or round.
stipple => bitmap: Indicates that the line should be filled in a stipple
pattern; bitmap specifies the stipple pattern to use.
tags => tagList: Specifies a set of tags to apply to the item. TagList
consists of a list of tag names, which replace any existing tags for the
item. TagList may be an empty list.
Rectangle Items
Items of type rectangle appear as rectangular regions on the display. Each
rectangle may have an outline, a fill, or both. Rectangles are created with
methods of the following form:
The TkcRectangle.new(canvas, x1, y1, x2, y2, ?option, value,...?) method
will be used to create a Rectangle.
The arguments x1, y1, x2, and y2 give the coordinates of two diagonally
opposite corners of the rectangle. Here is the description of other options:
fill => color: Fills the area of the rectangle with color.
315
Ruby
outline => color: Draws an outline around the edge of the rectangle in
color.
tags => tagList: Specifies a set of tags to apply to the item. TagList
consists of a list of tag names, which replace any existing tags for the
item. TagList may be an empty list.
Event Bindings
Canvas has the default bindings to allow scrolling if necessary: <Up>, <Down>,
<Left> and <Right> (and their <Control-*> counter parts). Further <Prior>,
<Next>, <Home> and <End>. These bindings allow you to navigate the same
way as in other widgets that can scroll.
Example 1
require "tk"
canvas = TkCanvas.new
Tk.mainloop
316
Ruby
Example 2
require 'tk'
root = TkRoot.new
root.title = "Window"
canvas = TkCanvas.new(root) do
place('height' => 170, 'width' => 100,
'x' => 10, 'y' => 10)
end
TkcLine.new(canvas, 0, 5, 100, 5)
TkcLine.new(canvas, 0, 15, 100, 15, 'width' => 2)
TkcLine.new(canvas, 0, 25, 100, 25, 'width' => 3)
TkcLine.new(canvas, 0, 35, 100, 35, 'width' => 4)
TkcLine.new(canvas, 0, 55, 100, 55, 'width' => 3,
'dash' => ".")
TkcLine.new(canvas, 0, 65, 100, 65, 'width' => 3,
'dash' => "-")
TkcLine.new(canvas, 0, 75, 100, 75, 'width' => 3,
'dash' => "-.")
TkcLine.new(canvas, 0, 85, 100, 85, 'width' => 3,
'dash' => "-..")
TkcLine.new(canvas, 0, 105, 100, 105, 'width' => 2,
'arrow' => "first")
TkcLine.new(canvas, 0, 115, 100, 115, 'width' => 2,
317
Ruby
Example 3
require 'tk'
root = TkRoot.new
root.title = "Window"
canvas = TkCanvas.new(root) do
place('height' => 170, 'width' => 100,
'x' => 10, 'y' => 10)
end
TkcRectangle.new(canvas, 10,
5,
55,
50,
'width' => 1)
TkcRectangle.new(canvas, 10,
65,
55, 110,
'width' => 5)
TkcRectangle.new(canvas, 10,
Ruby
=> "red")
Tk.mainloop
This will produce the following result:
Example 4
require 'tk'
root = TkRoot.new
root.title = "Window"
canvas = TkCanvas.new(root) do
place('height' => 170, 'width' => 100,
'x' => 10, 'y' => 10)
end
TkcLine.new(canvas, 0,
10, 100,
10,
30, 100,
30,
50, 100,
50,
70, 100,
70,
Ruby
TkcLine.new(canvas, 0,
90, 100,
90,
TkScale
Description
A Scale is a widget that displays a rectangular trough and a small slider. The
trough corresponds to a range of real values (determined by the from, to, and
resolution options), and the position of the slider selects a particular real value.
Three annotations may be displayed in a scale widget:
A label appearing at the top right of the widget (top left for horizontal
scales).
A number displayed just to the left of the slider (just above the slider for
horizontal scales).
A collection of numerical tick marks just to the left of the current value
(just below the trough for horizontal scales).
320
Ruby
Syntax
Here is a simple syntax to create this widget:
TkScale.new{
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
background
borderwidth
cursor
font
foreground
highlightbackground
highlightcolor
highlightthickness
orient
relief
repeatdelay
repeatinterval
takefocus
troughcolor
Widget-Specific Options
SN
321
Ruby
bigincrement =>Integer
Some interactions with the scale cause its value to change by large
increments; this option specifies the size of the large increments. If
specified as 0, the large increments default to 1/10 the range of the
scale.
command =>String
Specifies the prefix of a Ruby/Tk callback to invoke whenever the scale's
value is changed via a method.
digits =>Integer
An integer specifying how many significant digits should be retained when
converting the value of the scale to a string. If the number is less than or
equal to zero, then the scale picks the smallest value that guarantees
that every possible slider position prints as a different string.
from =>Integer
A real value corresponding to the left or top end of the scale.
label =>String
A string to display as a label for the scale. For vertical scales the label is
displayed just to the right of the top end of the scale. For horizontal
scales the label is displayed just above the left end of the scale.
length =>Integer
Specifies the desired long dimension of the scale in screen units
resolution =>Integer
A real value specifying the resolution for the scale. If this value is greater
than zero then the scale's value will always be rounded to an even
multiple of this value, as will tick marks and the endpoints of the scale. If
the value is less than zero then no rounding occurs. Defaults to 1
showvalue =>Boolean
Specifies a boolean value indicating whether or not the current value of
the scale is to be displayed.
322
Ruby
sliderlength =>Integer
Specfies the size of the slider, measured in screen units along the slider's
long dimension.
10
sliderrelief =>String
Specifies the relief to use when drawing the slider, such as raised or
sunken.
11
state =>String
Specifies one of three states for the scale: normal, active, or disabled.
12
tickinterval =>Integer
Must be a real value. Determines the spacing between numerical tick
marks displayed below or to the left of the slider. If 0, no tick marks will
be displayed.
13
to =>Integer
Specifies a real value corresponding to the right or bottom end of the
scale. This value may be either less than or greater than the from option.
14
variable =>Variable
Specifies the name of a global variable to link to the scale. Whenever the
value of the variable changes, the scale will update to reflect this value.
Whenever the scale is manipulated interactively, the variable will be
modified to reflect the scale's new value.
15
width =>Integer
Specifies the desired narrow dimension of the trough in screen units
Manipulating Scales
The following methods are available for scale widgets:
323
Ruby
get(?x, y?) If x and y are omitted, returns the current value of the scale.
If x and y are specified, they give pixel coordinates within the widget; the
command returns the scale value corresponding to the given pixel.
identify(x, y) Returns a string indicating what part of the scale lies under
the coordinates given by x and y. A return value of slider means that the
point is over the slider; trough1 means that the point is over the portion
of the slider above or to the left of the slider; and trough2 means that the
point is over the portion of the slider below or to the right of the slider.
Event Bindings
Ruby/Tk automatically creates class bindings for scales that give them the
following default behavior. Where the behavior is different for vertical and
horizontal scales, the horizontal behavior is described in parentheses.
If button 1 is pressed over the slider, the slider can be dragged with the
mouse.
If button 1 is pressed in the trough with the Control key down, the slider
moves all the way to the end of its range, in the direction towards the
mouse cursor.
If button 2 is pressed, the scale's value is set to the mouse position. If the
mouse is dragged with button 2 down, the scale's value changes with the
drag.
The Up and Left keys move the slider up (left) by the value of the
resolution option.
The Down and Right keys move the slider down (right) by the value of the
resolution option.
Control-Up and Control-Left move the slider up (left) by the value of the
bigIncrement option.
Control-Down and Control-Right move the slider down (right) by the value
of the bigIncrement option.
Home moves the slider to the top (left) end of its range.
End moves the slider to the bottom (right) end of its range.
324
Ruby
If the scale is disabled using the state option, then none of the above bindings
have any effect.
Examples
require "tk"
$scale = TkScale.new {
orient 'horizontal'
length 280
from 0
to 250
command (proc {printheight})
tickinterval 50
pack
}
def printheight
height = $scale.get()
print height, "\n"
end
Tk.mainloop
This will produce the following result:
325
Ruby
TkText
Description
A Text widget provides users with an area so that they can enter multiple lines
of text. Text widgets are part of the classic Tk widgets, not the themed Tk
widgets.
Text widgets support three different kinds of annotations on the text:
A label can display a textual string, bitmap or image. If text is displayed, it must
all be in a single font, but it can occupy multiple lines on the screen (if it
contains newlines or if wrapping occurs because of the wraplength option) and
one of the characters may optionally be underlined using the underline option.
Syntax
Here is a simple syntax to create this widget:
TkText.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
background
borderwidth
cursor
exportselection
font
foreground
326
Ruby
highlightbackground
highlightcolor
highlightthickness
insertbackground
insertborderwidth
insertofftime
insertontime
insertwidth
padx
pady
relief
selectbackground
selectborderwidth
selectforeground
setgrid
takefocus
xscrollcommand
yscrollcommand
Widget-Specific Options
SN
1
Ruby
Manipulating Test
The following useful methods are available to manipulate the content of a text:
328
Ruby
Event Bindings
Ruby/Tk automatically creates class bindings for texts. Here are few important
bindings listed.
Clicking mouse button 1 positions the insertion cursor just before the
character underneath the mouse cursor, sets the input focus to this
widget, and clears any selection in the widget. Dragging with mouse
button 1 strokes out a selection between the insertion cursor and the
character under the mouse.
329
Ruby
Double-clicking with mouse button 1 selects the word under the mouse
and positions the insertion cursor at the beginning of the word. Dragging
after a double click will stroke out a selection consisting of whole words.
Triple-clicking with mouse button 1 selects the line under the mouse and
positions the insertion cursor at the beginning of the line. Dragging after a
triple click will stroke out a selection consisting of whole lines.
Clicking mouse button 1 with the Control key down will reposition the
insertion cursor without affecting the selection.
The Left and Right keys move the insertion cursor one character to the
left or right; they also clear any selection in the text.
The Up and Down keys move the insertion cursor one line up or down and
clear any selection in the text. If Up or Right is typed with the Shift key
down, then the insertion cursor moves and the selection is extended to
include the new character.
Examples
require 'tk'
root = TkRoot.new
root.title = "Window"
text = TkText.new(root) do
width 30
height 20
borderwidth 1
font TkFont.new('times 12 bold')
pack("side" => "right",
end
text.insert 'end', "Hello!\n\ntext widget example"
Tk.mainloop
330
Ruby
TkToplevel
Description
A Toplevel is similar to a frame except that it is created as a top-level window.
Its X parent is the root window of a screen rather than the logical parent from its
path name.
The primary purpose of a toplevel is to serve as a container for dialog boxes and
other collections of widgets. The only visible features of a toplevel are its
background color and an optional 3-D border to make the toplevel appear raised
or sunken.
Syntax
Here is a simple syntax to create this widget:
TkToplevel.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
borderwidth
cursor
highlightbackground
highlightcolor
highlightthickness
relief
331
Ruby
takefocus
Widget-Specific Options
SN
1
Event Bindings
When a new toplevel is created, it has no default event bindings: toplevels are
not intended to be interactive.
Examples
require 'tk'
332
Ruby
def make_win
begin
$win.destroy
rescue
end
$win = TkToplevel.new
TkButton.new($win) {
text 'Window Dismiss'
command "$win.destroy"
pack
}
end
TkButton.new {
text 'make Window'
command 'make_win'
pack('fill' => 'x')
}
Tk.mainloop
This will produce the following result:
TkSpinbox
Description
A Spinbox widget allows users to choose numbers (or in fact, items from an
arbitrary list). It does this by combining an entry-like widget showing the current
333
Ruby
value with a pair of small up/down arrows which can be used to step through the
range of possible choices.
Spinboxes are capable of displaying strings that are too long to fit entirely within
the widget's window. In this case, only a portion of the string will be displayed;
commands described below may be used to change the view in the window.
Spinboxes use the standard xscrollcommand mechanism for interacting with
scrollbars.
Syntax
Here is a simple syntax to create this widget:
TkSpinbox.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
activebackground
background
borderwidth
cursor
exportselection
font
foreground
highlightbackground
highlightcolor
highlightthickness
justify
relief
repeatdelay
repeatinterval
selectbackground
selectborderwidth
334
Ruby
selectforeground
takefocus
textvariable
xscrollcommand
Widget-Specific Options
SN
1
Ruby
10
11
to => Integer
A floating-point value corresponding to the highest value for the Spinbox,
to be used in conjunction with from and increment. When all are
specified correctly, the Spinbox will use these values to control its
contents. This value must be greater than the from option. If values is
specified, it supercedes this option.
12
13
14
15
Ruby
Validation Stages
Validation works by setting the validatecommand option to a callback, which
will be evaluated according to the validate option as follows:
Manipulating Spinbox
Here is a list of few important methods to play with Spinbox:
Ruby
set(?string?) : f string is specified, the Spinbox will try and set it to this
value, otherwise it just returns the Spinbox's string. If validation is on, it
will occur when setting the string.
Event Bindings
Tk automatically creates class bindings for Spinboxes that gives them the default
behavior. Few important behaviors are given below:
Clicking mouse button 1, positions the insertion cursor just before the
character underneath the mouse cursor, sets the input focus to this
widget, and clears any selection in the widget. Dragging with mouse
button 1, strokes out a selection between the insertion cursor and the
character under the mouse.
Double-clicking with mouse button 1, selects the word under the mouse
and positions the insertion cursor at the beginning of the word. Dragging
after a double click will stroke out a selection consisting of whole words.
Triple-clicking with mouse button 1, selects all of the text in the Spinbox
and positions the insertion cursor before the first character.
The ends of the selection can be adjusted by dragging with mouse button
1, while the Shift key is down; this will adjust the end of the selection that
was nearest to the mouse cursor when button 1 was pressed. If the
button is double-clicked before dragging then the selection will be
adjusted in units of whole words.
Clicking mouse button 1 with the Control key down, will position the
insertion cursor in the Spinbox without affecting the selection.
If any normal printing characters are typed in a Spinbox, they are inserted
at the point of the insertion cursor.
The view in the Spinbox can be adjusted by dragging with mouse button
2. If mouse button 2 is clicked without moving the mouse, the selection is
copied into the Spinbox at the position of the mouse cursor.
If the mouse is dragged out of the Spinbox on the left or right sides while
button 1 is pressed, the Spinbox will automatically scroll to make more
338
Ruby
text visible (if there is more text off-screen on the side where the mouse
left the window).
The End key, or Control-e, will move the insertion cursor to the end of the
Spinbox and clear any selection in the Spinbox. Shift-End moves the
cursor to the end and extends the selection to that point.
The Home key, or Control-a, will move the insertion cursor to the
beginning of the Spinbox and clear any selection in the Spinbox. ShiftHome moves the insertion cursor to the beginning of the Spinbox and also
extends the selection to that point.
The Delete key deletes the selection, if there is one in the Spinbox. If
there is no selection, it deletes the character to the right of the insertion
cursor.
The BackSpace key and Control-h delete the selection, if there is one in
the Spinbox. If there is no selection, it deletes the character to the left of
the insertion cursor.
Control-k deletes all the characters to the right of the insertion cursor.
Examples
require 'tk'
root = TkRoot.new
root.title = "Window"
Sb = TkSpinbox.new(root) do
to 100
from 5
increment 5
pack("side" => "left",
end
Tk.mainloop
This will produce the following result:
339
Ruby
TkProgressBar
Description
A ProgressBar provides a widget, which will show a graphical representation of
a value, given maximum and minimum reference values.
Syntax
Here is a simple syntax to create this widget:
Tk::ProgressBar.new(root) {
.....Standard Options....
.....Widget-specific Options....
}
Standard Options
borderwidth
highlightthickness
padx
pady
relief
troughcolor
Widget-Specific Options
SN
340
Ruby
to => Integer
This sets the upper limit of the progress bar. If a value is specified (for
example, using the value method) that lies above this value the full
progress bar will be displayed. Defaults to 100.
Ruby
11
Examples
require 'tk'
require 'tkextlib/bwidget'
root = TkRoot.new
root.title = "Window"
progressBar = Tk::BWidget::ProgressBar.new(root)
variable = TkVariable.new
progressBar.variable = variable
variable.value = 33
progressBar.maximum = 100
progressBar.place('height' => 25,
'width'
=> 100,
'x'
=> 10,
'y'
=> 10)
342
Ruby
Tk.mainloop
This will produce the following result:
Dialog Box
Description
Dialog boxes are a type of window used in applications to get some information
from the user, inform them that some event has occurred, confirm an action and
more.
The appearance and usage of dialog boxes is usually quite specifically detailed in
a platform's style guide. Tk comes with a number of dialog boxes built-in for
common tasks, and which help you conform to platform specific style guidelines.
Examples
Following example will explain how to create Open file dialog box.
require 'tk'
root = TkRoot.new
343
Ruby
root.title = "Window"
button_click = Proc.new {
Tk.getOpenFile
}
button = TkButton.new(root) do
text "button"
pack("side" => "left",
end
button.comman = button_click
Tk.mainloop
This will produce the following result:
Following example will explain how to create Choose Color dialog box.
require 'tk'
root = TkRoot.new
root.title = "Window"
button_click = Proc.new {
Tk.chooseColor
344
Ruby
button = TkButton.new(root) do
text "button"
pack("side" => "left",
end
button.comman = button_click
Tk.mainloop
This will produce the following result:
Tk::Tile::Notebook
The NoteBook widget provides a notebook metaphor to display several windows
in limited space. The notebook is divided into a stack of pages of which only one
is displayed at any time.
The other pages can be selected by means of choosing the visual tabs at the top
of the widget. Additionally, the <Tab> key may be used to traverse the pages. If
underline option is used, Alt-bindings will also work.
Syntax
Here is a simple syntax to create this widget:
Tk::Tile::Notebook.new(root) {
345
Ruby
.....Standard Options....
.....Widget Specific Options....
}
Standard Options
class
cursor
state
style
takefocus
Widget-Specific Options
SN
1
Manipulating Notebook
There are various ways to play with Notebook:
Ruby
end of the list of tabs with the "add subwindow ?option value...?"
method.
The text tab option is used to set the label on the tab; also useful is the
state tab option, which can have the value normal, disabled (not
selectable), or hidden.
To insert a tab at somewhere other than the end of the list, you can use
the"insert position subwindow ?option value...?", and to remove a
given tab, use the forget method, passing it either the position (0..n-1) or
the tab's subwindow. You can retrieve the list of all subwindows contained
in the notebook via the tabs method.
To change a tab option you can use the "itemconfigure tabid, :option
=> value"method. Where tabid is the tab's position or subwindow. You
can use the"itemcget tabid, :option" to return the current value of the
option.
Examples
require 'tk'
require 'tkextlib/tile'
root = TkRoot.new
root.title = "Window"
n = Tk::Tile::Notebook.new(root)do
height 110
place('height' => 100, 'width' => 200, 'x' => 10, 'y' => 10)
end
f1 = TkFrame.new(n)
f2 = TkFrame.new(n)
f3 = TkFrame.new(n)
Ruby
Tk.mainloop
This will produce the following result:
Tk::Tile::Paned
The Panedwindow widget lets you stack two or more resizable widgets above
and below each other (or to the left and right).
The user can adjust the relative heights (or widths) of each pane by dragging a
sash located between them. Typically, the widgets you're adding to a
panedwindow will be frames containing many other widgets.
Syntax
Here is a simple syntax to create this widget:
Tk::Tile::Paned.new(root) {
.....Standard Options....
.....Widget Specific Options....
}
Standard Options
class
cursor
style
takefocus
348
Ruby
Widget-Specific Options
SN
1
Manipulating Paned
Calling the "add" method will add a new pane at the end of the list of
panes. The"insert position subwindow" method allows you to place the
pane at the given position in the list of panes (0..n-1); if the pane is
already managed by the panedwindow, it will be moved to the new
position. You can use the "forgetsubwindow" to remove a pane from
the panedwindow; you can also pass a position instead of a subwindow.
Other options let you sign relative weights to each pane so that if the
overall panedwindow resizes, certain panes will get more space than
others. As well, you can adjust the position of each sash between items in
the panedwindow. See the command reference for details.
Examples
require 'tk'
require 'tkextlib/tile'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
349
Ruby
p = Tk::Tile::Paned.new(root)do
height 110
place('height' => 100, 'width' => 200, 'x' => 10, 'y' => 10)
end
f1 = TkFrame.new(p) {
relief 'groove'
borderwidth 3
background "red"
padx 30
pady 30
pack('side' => 'left', 'pady' => 100)
}
f2 = TkFrame.new (p){
relief 'groove'
borderwidth 3
background "yellow"
padx 30
pady 30
pack('side' => 'right', 'pady' => 100)
}
Tk.mainloop
350
Ruby
Tk::Tile::Separator
The Separator widget provides a convenient way of dividing a window into
logical parts. You can group widgets in one display using a thin horizontal or
vertical rule between groups of widgets.
Syntax
Here is a simple syntax to create this widget:
Tk::Tile::Separator.new(root) {
.....Standard Options....
.....Widget Specific Options....
}
Standard Options
class
cursor
state
style
takefocus
Widget-Specific Options
SN
1
351
Ruby
Examples
require 'tk'
require 'tkextlib/tile'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
n = Tk::Tile::Notebook.new(root)do
height 110
place('height' => 100, 'width' => 200, 'x' => 10, 'y' => 10)
end
f1 = TkFrame.new(n)
f2 = TkFrame.new(n)
f3 = TkFrame.new(n)
s1 = Tk::Tile::Separator.new(f1) do
orient 'vertical'
place('height' => 200, 'x' => 40, 'y' => 10)
end
s2 = Tk::Tile::Separator.new(f1) do
orient 'vertical'
place('height' => 200, 'x' => 80, 'y' => 10)
end
Tk.mainloop
352
Ruby
Description
TkDefaultFont
TkTextFont
TkFixedFont
TkMenuFont
TkHeadingFont
TkCaptionFont
TkTooltipFont
Ruby
Standard Options
You can specify one or more standard option separated by comma.
Foundry
Family
Weight
Slant
Swidth
Pixel
Point
Xres
Yres
Space
Avgwidth
Registry
Encoding
Ruby/Tk Colors
There are various ways to specify colors. Full details can be found in the colors
command reference.
The system will provide the right colors for most things. Like with fonts, both
Mac and Windows specifies a large number of system-specific color names (see
the reference).
You can also specify fonts via RGB, like in HTML, e.g. "#3FF" or "#FF016A".
Finally, Tk recognizes the set of color names defined by X11; normally these are
not used, except for very common ones such as "red", "black", etc.
354
Ruby
For themed Tk widgets, colors are often used in defining styles that are applied
to widgets, rather than applying the color to a widget directly.
Examples
require 'tk'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
myFont = TkFont.new("family" => 'Helvetica',
"size" => 20,
"weight" => 'bold')
Lbl = TkLabel.new(root) do
textvariable
borderwidth 5
font myFont
foreground
"red"
relief
"groove"
end
Lbl['textvariable'] = $resultsVar
$resultsVar.value = 'New value to display'
Tk.mainloop
355
Ruby
Ruby/Tk Images
Ruby/Tk includes support for GIF and PPM/PNM images. However, there is a Tk
extension library called "Img", which adds support for many others: BMP, XBM,
XPM, PNG, JPEG, TIFF, etc. Though not included directly in the Tk core, Img is
usually included with other packaged distributions.
Here, we will see the basics of how to use images, displaying them in labels or
buttons for example. We create an image object, usually from a file on disk.
Examples
require 'tk'
$resultsVar = TkVariable.new
root = TkRoot.new
root.title = "Window"
image = TkPhotoImage.new
image.file = "zara.gif"
label = TkLabel.new(root)
label.image = image
label.place('height' => image.height,
'width' => image.width,
'x' => 10, 'y' => 10)
Tk.mainloop
Ruby
Tk's images are actually quite powerful and sophisticated and provide a wide
variety of ways to inspect and modify images. You can find out more from the
image command reference and the photo command reference.
Ruby
10
11
358
Ruby
12
13
14
15
16
17
18
19
Ruby
means that the lines' centers are aligned, and right means that the lines'
right edges line up.
20
21
22
23
24
25
26
27
Ruby
28
29
30
31
32
33
34
Ruby
36
37
38
39
40
362
Ruby
combines it with any parameters provided by the program when it asks the
geometry manager to manage that particular slave widget.
There are three geometry managers place, grid and pack that are responsible for
controlling the size and location of each of the widgets in the interface.
grid
Description
The grid geometry manager is the most flexible and easy-to-use geometry
manager. It logically divides the parent window or the widget into rows and
columns in a two-dimensional table.
You can then place a widget in an appropriate row and column format by using
the row and column options, respectively. To understand the use of row and
column options, consider the following example.
Syntax
Here is a simple syntax to create a grid Widget:
grid('row'=>x, 'column'=>y)
Examples
Following is the code to display the Label and an Entry widget using the grid
geometry manager:
require 'tk'
Ruby
grid('row'=>0, 'column'=>0)
}
Tk.mainloop
This will produce the following result:
Pack
Description
The pack geometry manager organizes widgets in rows or columns inside the
parent window or the widget. To manage widgets easily, the pack geometry
manager provides various options, such as fill, expand, and side.
fill: The fill option is used to specify whether a widget should occupy all
the space given to it by the parent window or the widget. Some of the
possible values that can be used with this option are none, x, y, or both.
By default, the fill option is set to none.
side: The side option is used to specify the side against which the widget
is to be packed. Some of the possible values that can be used with this
option are top, left, bottom, or right. By default, the widgets are packed
against the top edge of the parent window.
364
Ruby
Syntax
Here is a simple syntax to create a pack Widget:
pack('padx'=>10, 'pady'=>10, 'side'=>'left')
Examples
Following is the code to display the Label and an Entry widget using the pack
geometry manager:
require 'tk'
Tk.mainloop
This will produce the following result:
365
Ruby
Place
Description
The place geometry manager allows you to place a widget at the specified
position in the window. You can specify the position either in absolute terms or
relative to the parent window or the widget.
To specify an absolute position, use the x and y options. To specify a position
relative to the parent window or the widget, use the relx and rely options.
In addition, you can specify the relative size of the widget by using the relwidth
and relheight options provided by this geometry manager.
Syntax
Here is a simple syntax to create a place Widget:
place(relx'=>x, 'rely'=>y)
Examples
Following is the code, which implements the place geometry manager:
require 'tk'
Ruby
Tk.mainloop
367
Ruby
For example, to catch the ButtonRelease event for the first mouse button on
some widget, you'd write:
someWidget.bind('ButtonRelease-1') {
....code block to handle this event...
}
An event name can include additional modifiers and details. A modifier is a string
like Shift, Control or Alt, indicating that one of the modifier keys was pressed.
So, for example, to catch the event that's generated when the user holds down
the Ctrl key and clicks the right mouse button
someWidget.bind('Control-ButtonPress-3', proc { puts "Ouch!" })
Many Ruby/Tk widgets can trigger callbacks when the user activates them, and
you can use the command callback to specify that a certain code block or
procedure is invoked when that happens. As seen earlier, you can specify the
command callback procedure when you create the widget:
helpButton = TkButton.new(buttonFrame) {
text "Help"
command proc { showHelp }
}
Or you can assign it later, using the widget's command method:
helpButton.command proc { showHelp }
Since the command method accepts either procedures or code blocks, you could
also write the previous code example as:
helpButton = TkButton.new(buttonFrame) {
text "Help"
command { showHelp }
}
You can use the following basic event types in your Ruby/Tk application:
Tag
"1" (one)
Event Description
Clicked left mouse button.
368
Ruby
"ButtonPress-1"
"Enter"
"Leave"
"Double-1"
Double clicked.
"B3-Motion"
Control-ButtonPress-3
Alt-ButtonPress-1
button = TkButton.new {
text 'Hello World!'
pack
}
button.configure('activebackground', 'blue')
Tk.mainloop
To get the value for a current widget, just supply it without a value as follows:
color = button.configure('activebackground')
You can also call configure without any options at all, which will give you a listing
of all options and their values.
369
Ruby
370
Ruby
30. LDAP
Ruby/LDAP Installation
You can download and
SOURCEFORGE.NET.
install
complete
Ruby/LDAP
package
from
Before installing Ruby/LDAP, make sure you have the following components:
Now, you can use standard Ruby Installation method. Before starting, if you'd
like to see the available options for extconf.rb, run it with '--help' option.
$ ruby extconf.rb [--with-openldap1|--with-openldap2| \
--with-netscape|--with-wldap32]
$ make
$ make install
NOTE: If you're building the software on Windows, you may need to use nmake
instead of make.
371
Ruby
port: This is the port being used for LDAP service. Standard LDAP ports
are 636 and 389. Make sure which port is being used at your server
otherwise you can use LDAP::LDAP_PORT.
This call returns a new LDAP::Conn connection to the server, host, on port port.
Step 2: Binding
This is where we usually specify the username and password we will use for the
rest of the session.
Following is the syntax to bind an LDAP connection, using the DN, dn, the
credential, pwd, and the bind method, method:
conn.bind(dn=nil, password=nil, method=LDAP::LDAP_AUTH_SIMPLE)do
....
end
You can use the same method without a code block. In this case, you would
need to unbind the connection explicitly as follows:
conn.bind(dn=nil, password=nil, method=LDAP::LDAP_AUTH_SIMPLE)
....
conn.unbind
If a code block is given, self is yielded to the block.
We can now perform search, add, modify or delete operations inside the block of
the bind method (between bind and unbind), provided we have the proper
permissions.
Example
Assuming we are working on a local server, let's put things together with
appropriate host, domain, user id and password, etc.
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
372
Ruby
This call returns LDAP::Mod object, which can be passed to methods in the
LDAP::Conn class, such as Conn#add, Conn#add_ext, Conn#modify and
Conn#modify_ext.
Example
Here is a complete example, which will create two directory entries:
373
Ruby
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn.perror("bind")
entry1 = [
LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','domain']),
LDAP.mod(LDAP::LDAP_MOD_ADD,'o',['TTSKY.NET']),
LDAP.mod(LDAP::LDAP_MOD_ADD,'dc',['localhost']),
}
entry2 = [
LDAP.mod(LDAP::LDAP_MOD_ADD,'objectclass',['top','person']),
LDAP.mod(LDAP::LDAP_MOD_ADD, 'cn', ['Zara Ali']),
LDAP.mod(LDAP::LDAP_MOD_ADD | LDAP::LDAP_MOD_BVALUES, 'sn',
['ttate','ALI', "zero\000zero"]),
]
begin
conn.add("dc=localhost, dc=localdomain", entry1)
conn.add("cn=Zara Ali, dc=localhost, dc=localdomain", entry2)
rescue LDAP::ResultError
conn.perror("add")
exit
end
conn.perror("add")
374
Ruby
conn.unbind
Example
To modify the surname of the entry, which we added in the previous section, we
would write:
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn.perror("bind")
entry1 = [
LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'sn', ['Mohtashim']),
]
begin
conn.modify("cn=Zara Ali, dc=localhost, dc=localdomain", entry1)
rescue LDAP::ResultError
conn.perror("modify")
375
Ruby
exit
end
conn.perror("modify")
conn.unbind
Example
To delete Zara Mohtashim entry, which we added in the previous section, we
would write:
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn.perror("bind")
begin
conn.delete("cn=Zara-Mohtashim, dc=localhost, dc=localdomain")
rescue LDAP::ResultError
conn.perror("delete")
exit
end
conn.perror("delete")
376
Ruby
conn.unbind
Example
Suppose we have the following entry:
dn: cn=Zara Ali,dc=localhost,dc=localdomain
cn: Zara Ali
sn: Ali
objectclass: person
Then, we can modify its distinguished name with the following code:
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn.perror("bind")
begin
conn.modrdn("cn=Zara Ali, dc=localhost, dc=localdomain",
377
Ruby
Performing a Search
To perform a search on a LDAP directory, use the search method with one of the
three different search modes:
Example
Here, we are going to search the whole subtree of entry dc=localhost,
dc=localdomain forperson objects:
#/usr/bin/ruby -w
require 'ldap'
$HOST =
'localhost'
$PORT =
LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
base = 'dc=localhost,dc=localdomain'
scope = LDAP::LDAP_SCOPE_SUBTREE
filter = '(objectclass=person)'
attrs = ['sn', 'cn']
Ruby
conn.perror("bind")
begin
conn.search(base, scope, filter, attrs) { |entry|
# print distinguished name
p entry.dn
# print all attribute names
p entry.attrs
# print values of attribute 'sn'
p entry.vals('sn')
# print entry as Hash
p entry.to_hash
}
rescue LDAP::ResultError
conn.perror("search")
exit
end
conn.perror("search")
conn.unbind
This invokes the given code block for each matching entry where the LDAP entry
is represented by an instance of the LDAP::Entry class. With the last parameter
of search, you can specify the attributes in which you are interested, omitting all
others. If you pass nil here, all attributes are returned same as "SELECT *" in
relational databases.
The dn method (alias for get_dn) of the LDAP::Entry class returns the
distinguished name of the entry, and with the to_hash method, you can get a
hash representation of its attributes (including the distinguished name). To get a
list of an entry's attributes, use the attrs method (alias for get_attributes). Also,
to get the list of one specific attribute's values, use the vals method (alias for
get_values).
Handling Errors
Ruby/LDAP defines two different exception classes:
379
Ruby
Further Reading
For complete details on LDAP methods,
documentation for LDAP Documentation.
please
refer
to
the
standard
380
31. MULTITHREADING
Ruby
Example
Here is an example, which shows how we can use multi-threaded Ruby program.
#!/usr/bin/ruby
def func1
i=0
while i<=2
puts "func1 at: #{Time.now}"
sleep(2)
381
Ruby
i=i+1
end
end
def func2
j=0
while j<=2
puts "func2 at: #{Time.now}"
sleep(1)
j=j+1
end
end
Thread Lifecycle
A new threads are created with Thread.new. You can also use the synonyms
Thread.start and Thread.fork.
382
Ruby
Thread Variables
A thread can normally access any variables that are in scope when the thread is
created. Variables local to the block of a thread are local to the thread, and are
not shared.
Thread class features a special facility that allows thread-local variables to be
created and accessed by name. You simply treat the thread object as if it were a
Hash, writing to elements using []= and reading them back using [].
383
Ruby
In this example, each thread records the current value of the variable count in a
threadlocal variable with the key mycount.
#!/usr/bin/ruby
count = 0
arr = []
10.times do |i|
arr[i] = Thread.new {
sleep(rand(0)/10.0)
Thread.current["mycount"] = count
count += 1
}
end
Thread Priorities
The first factor that affects the thread scheduling is the thread priority: highpriority threads are scheduled before low-priority threads. More precisely, a
thread will only get CPU time if there are no higher-priority threads waiting to
run.
You can set and query the priority of a Ruby Thread object with priority= and
priority. A newly created thread starts at the same priority as the thread that
created it. The main thread starts off at priority 0.
There is no way to set the priority of a thread before it starts running. A thread
can, however, raise or lower its own priority as the first action it takes.
384
Ruby
Thread Exclusion
If two threads share access to the same data, and at least one of the threads
modifies that data, you must take special care to ensure that no thread can ever
see the data in an inconsistent state. This is called thread exclusion.
Mutex is a class that implements a simple semaphore lock for mutually
exclusive access to some shared resource. That is, only one thread may hold the
lock at a given time. Other threads may choose to wait in line for the lock to
become available, or may simply choose to get an immediate error indicating
that the lock is not available.
By placing all accesses to the shared data under control of a mutex, we ensure
consistency and atomic operation. Let's try to examples, first one without mutax
and second one with mutax:
count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
count1 += 1
count2 += 1
end
end
spy = Thread.new do
loop do
difference += (count1 - count2).abs
end
end
sleep 1
puts "count1 :
#{count1}"
puts "count2 :
#{count2}"
Ruby
count1 :
1583766
count2 :
1583766
difference : 637992
#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new
count1 = count2 = 0
difference = 0
counter = Thread.new do
loop do
mutex.synchronize do
count1 += 1
count2 += 1
end
end
end
spy = Thread.new do
loop do
mutex.synchronize do
difference += (count1 - count2).abs
end
end
end
sleep 1
mutex.lock
puts "count1 :
#{count1}"
puts "count2 :
#{count2}"
696591
386
Ruby
count2 :
696591
difference : 0
Handling Deadlock
When we start using Mutex objects for thread exclusion we must be careful to
avoid deadlock. Deadlock is the condition that occurs when all threads are
waiting to acquire a resource held by another thread. Because all threads are
blocked, they cannot release the locks they hold. And because they cannot
release the locks, no other thread can acquire those locks.
This is where condition variables come into picture. A condition variable is simply
a semaphore that is associated with a resource and is used within the protection
of a particular mutex. When you need a resource that's unavailable, you wait on
a condition variable. That action releases the lock on the corresponding mutex.
When some other thread signals that the resource is available, the original
thread comes off the wait and simultaneously regains the lock on the critical
region.
Example
#!/usr/bin/ruby
require 'thread'
mutex = Mutex.new
cv = ConditionVariable.new
a = Thread.new {
mutex.synchronize {
puts "A: I have critical section, but will wait for cv"
cv.wait(mutex)
puts "A: I have critical section again! I rule!"
}
}
b = Thread.new {
mutex.synchronize {
387
Ruby
Thread States
There are five possible return values corresponding to the five possible states as
shown in the following table. The status method returns the state of the thread.
Thread state
Return value
Runnable
run
Sleeping
Sleeping
Aborting
aborting
Terminated normally
false
nil
Ruby
Thread.abort_on_exception = true
Here is the complete list of all the class methods available:
SN
1
Thread.abort_on_exception=
When set to true, all threads will abort if an exception is raised. Returns
the new state.
Thread.critical
Returns the status of the global thread critical condition.
Thread.critical=
Sets the status of the global thread critical condition and returns it. When
set to true, prohibits scheduling of any existing thread. Does not block
new threads from being created and run. Certain thread operations (such
as stopping or killing a thread, sleeping in the current thread, and raising
an exception) may cause a thread to be scheduled even when in a critical
section.
Thread.current
Returns the currently executing thread.
Thread.exit
Terminates the currently running thread and schedules another thread to
be run. If this thread is already marked to be killed, exit returns the
Thread. If this is the main thread, or the last thread, exit the process.
Thread.fork { block }
Synonym for Thread.new.
389
Ruby
Thread.kill( aThread )
Causes the given aThread to exit.
Thread.list
Returns an array of Thread objects for all threads that are either runnable
or stopped. Thread.
10
Thread.main
Returns the main thread for the process.
11
12
Thread.pass
Invokes the thread scheduler to pass execution to another thread.
13
14
Thread.stop
Stops execution of the current thread, putting it into a sleep state, and
schedules execution of another thread. Resets the critical condition to
false.
thr = Thread.new do
Ruby
thr[ aSymbol ] =
Attribute Assignment - Sets or creates the value of a thread-local
variable, using either a symbol or a string.
thr.abort_on_exception
Returns the status of the abort on exception condition for thr. The default
is false.
thr.abort_on_exception=
When set to true, causes all threads (including the main program) to
abort if an exception is raised in thr. The process will effectively exit(0).
thr.alive?
Returns true if thr is running or sleeping.
thr.exit
Terminates thr and schedules another thread to be run. If this thread is
already marked to be killed, exit returns the Thread. If this is the main
thread, or the last thread, exits the process.
thr.join
The calling thread will suspend execution and run thr. Does not return
until thr exits. Any threads not joined will be killed when the main
391
Ruby
program exits.
8
thr.key?
Returns true if the given string (or symbol) exists as a thread-local
variable.
thr.kill
Synonym for Thread.exit .
10
thr.priority
Returns the priority of thr. Default is zero; higher-priority threads will run
before lower priority threads.
11
thr.priority=
Sets the priority of thr to an Integer. Higher-priority threads will run
before lower priority threads.
12
thr.raise( anException )
Raises an exception from thr. The caller does not have to be thr.
13
thr.run
Wakes up thr, making it eligible for scheduling. If not in a critical section,
then invokes the scheduler.
14
thr.safe_level
Returns the safe level in effect for thr.
15
thr.status
Returns the status of thr: sleep if thr is sleeping or waiting on I/O, run if
thr is executing, false if thr terminated normally, and nil if thr terminated
with an exception.
16
thr.stop?
Returns true if thr is dead or sleeping.
392
Ruby
17
thr.value
Waits for thr to complete via Thread.join and returns its value.
18
thr.wakeup
Marks thr as eligible for scheduling, it may still remain blocked on I/O,
however.
393
Ruby
Since the Kernel module is included by Object class, its methods are available
everywhere in the Ruby program. They can be called without a receiver
(functional form). Therefore, they are often called functions.
A complete list of Built-in Functions is given here for your reference:
SN
1
Array( obj)
Returns obj after converting it to an array using to_ary or to_a.
at_exit {...}
Registers a block for execution when the program exits. Similar to END
statement, but END statement registers the block only once.
binding
Returns the current variable and method bindings. The Binding object that
is returned may be passed to the eval method as its second argument.
block_given?
Returns true if the method was called with a block.
callcc {| c|...}
Passes a Continuation object c to the block and executes the block. callcc
can be used for global exit or loop construct.
394
Ruby
caller([ n])
Returns the current execution stack in an array of the strings in the form
file:line. If n is specified, returns stack entries from nth level on down.
10
chomp([ rs=$/])
Returns the value of variable $_ with the ending newline removed,
assigning the result back to $_. The value of the newline string can be
specified with rs.
11
chomp!([ rs=$/])
Removes newline from $_, modifying the string in place.
12
chop
Returns the value of $_ with its last character (one byte) removed,
assigning the result back to $_.
13
chop!
Removes the last character from $_, modifying the string in place.
14
15
16
exit([ result=0])
Exits program, with result as the status code returned.
395
Ruby
17
exit!([ result=0])
Kills the program bypassing exit handling such as ensure, etc.
18
fail(...)
See raise(...).
19
Float( obj)
Returns obj after converting it to a float. Numeric objects are converted
directly; nil is converted to 0.0; strings are converted considering 0x, 0b
radix prefix. The rest are converted using obj.to_f.
20
fork
fork {...}
Creates a child process. nil is returned in the child process and the child
process' ID (integer) is returned in the parent process. If a block is
specified, it's run in the child process.
21
22
gets([ rs=$/])
Reads the filename specified in the command line or one line from
standard input. The record separator string can be specified explicitly
with rs.
23
global_variables
Returns an array of global variable names.
24
gsub( x, y)
gsub( x) {...}
Replaces all strings matching x in $_ with y. If a block is specified,
matched strings are replaced with the result of the block. The modified
result is assigned to $_.
25
gsub!( x, y)
gsub!( x) {...}
Performs the same substitution as gsub, except the string is changed in
396
Ruby
place.
26
Integer( obj)
Returns obj after converting it to an integer. Numeric objects are
converted directly; nil is converted to 0; strings are converted
considering 0x, 0b radix prefix. The rest are converted using obj.to_i.
27
lambda {| x|...}
proc {| x|...}
lambda
proc
Converts a block into a Proc object. If no block is specified, the block
associated with the calling method is converted.
28
29
local_variables
Returns an array of local variable names.
30
loop {...}
Repeats a block of code.
31
32
p( obj)
Displays obj using its inspect method (often used for debugging).
397
Ruby
33
print([ arg...])
Prints arg to $defout. If no arguments are specified, the value of $_ is
printed.
34
35
proc {| x|...}
proc
See lamda.
36
putc( c)
Prints one character to the default output ($defout).
37
puts([ str])
Prints string to the default output ($defout). If the string doesn't end with
a newline, a newline is appended to the string.
38
raise(...)
fail(...)
Raises an exception. Assumes RuntimeError if no exception class is
specified. Calling raise without arguments in a rescue clause re-raises the
exception. Doing so outside a rescue clause raises a message-less
RuntimeError. fail is an obsolete name for raise.
39
rand([ max=0])
Generates a pseudo-random number greater than or equal to 0 and less
than max. If max is either not specified or is set to 0, a random number
is returned as a floating-point number greater than or equal to 0 and less
than 1. srand may be used to initialize pseudo-random stream.
40
readline([ rs=$/])
Equivalent to gets except it raises an EOFError exception on reading EOF.
41
readlines([ rs=$/])
398
Ruby
require( lib)
Loads the library (including extension libraries) lib when it's first called.
require will not load the same library more than once. If no extension is
specified in lib, require tries to add .rb,.so, etc., to it.
43
scan( re)
scan( re) {|x|...}
Equivalent to $_.scan.
44
45
set_trace_func( proc)
Sets a handler for tracing. proc may be a string or proc object.
set_trace_func is used by the debugger and profiler.
46
sleep([ sec])
Suspends program execution for sec seconds. If sec isn't specified, the
program is suspended forever.
47
48
Ruby
49
srand([ seed])
Initializes an array of random numbers. If seed isn't specified,
initialization is performed using the time and other system information for
the seed.
50
String( obj)
Returns obj after converting it to a string using obj.to_s.
51
52
53
sub( x, y)
sub( x) {...}
Replaces the first string matching x in $_ with y. If a block is specified,
matched strings are replaced with the result of the block. The modified
result is assigned to $_.
54
sub!( x, y)
sub!( x) {...}
Performs the same replacement as sub, except the string is changed in
place.
55
56
Ruby
58
59
num = 12.40
puts num.floor
# 12
puts num + 10
# 22.40
puts num.integer?
# false
as num is a float.
401
Ruby
Assuming, n is a number:
SN
1
n % num
Returns the modulus of n.
n ** num
Exponentiation.
n.abs
Returns the absolute value of n.
n.ceil
Returns the smallest integer greater than or equal to n.
n.coerce( num)
Returns an array containing num and n both possibly converted to a
type that allows them to be operated on mutually. Used in automatic
type conversion in numeric operators.
n.divmod( num)
Returns an array containing the quotient and modulus from dividing n
by num.
n.floor
Returns the largest integer less than or equal to n.
402
Ruby
n.integer?
Returns true if n is an integer.
10
n.modulo( num)
Returns the modulus obtained by dividing n by num and rounding the
quotient with floor
11
n.nonzero?
Returns n if it isn't zero, otherwise nil.
12
n.remainder( num)
Returns the remainder obtained by dividing n by num and removing
decimals from the quotient. The result and n always have same sign.
13
n.round
Returns n rounded to the nearest integer.
14
n.truncate
Returns n as an integer with decimals removed.
15
n.zero?
Returns zero if n is 0.
16
17
n << num
n >> num
Bitwise left shift and right shift.
18
n[num]
Returns the value of the numth bit from the least significant bit, which
is n[0].
403
Ruby
19
n.chr
Returns a string containing the character for the character code n.
20
n.next
n.succ
Returns the next integer following n. Equivalent to n + 1.
21
n.size
Returns the number of bytes in the machine representation of n.
22
23
24
n.to_f
Converts n into a floating point number. Float conversion may lose
precision information.
25
n.to_int
Returns n after converting into interger number.
f.finite?
404
Ruby
f.infinite?
Returns 1 if f is positive infinity, -1 if negative infinity, or nil if anything
else.
f.nan?
Returns true if f isn't a valid IEEE floating point number.
cos( x)
Calculates the cosine of x.
exp( x)
Calculates an exponential function (e raised to the power of x).
frexp( x)
Returns a two-element array containing the nominalized fraction and
exponent of x.
ldexp( x, exp)
Returns the value of x times 2 to the power of exp.
log( x)
Calculates the natural logarithm of x.
log10( x)
405
Ruby
sin( x)
Calculates the sine of x.
sqrt( x)
Returns the square root of x. x must be positive.
10
tan( x)
Calculates the tangent of x.
Description
Binary integer
Single character
d,i
Decimal integer
406
Ruby
Octal integer
puts str
puts str
puts str
puts str
407
Ruby
Description
?r
?w
?x
?o
?R
?W
?X
?O
?e
Does f1 exist?
?z
?s
Ruby
?f
Is f1 a regular file?
?d
Is f1 a directory?
?l
Is f1 a symbolic link?
?p
?S
Is f1 a socket?
?b
Is f1 a block device?
?c
Is f1 a character device?
?u
?g
?k
?M
?A
?C
Description
?=
?>
?<
409
Ruby
?-
Is f1 a hard link to f2 ?
Following is the usage example. Assuming main.rb exist with read, write and not
execute permissions:
#!/usr/bin/ruby
# => true
# => true
# => false
410
Ruby
Ruby's predefined variables affect the behavior of the entire program, so their
use in libraries is not recommended.
The values in most predefined variables can be accessed by alternative means.
Following table lists all the Ruby's predefined variables.
Variable Name
Description
$!
$@
$/
$\
$,
$;
$.
The number of the last line read from the current input
file. Equivalent to ARGF.lineno.
$<
$>
$0
Ruby
$$
$?
$:
$DEBUG
$defout
$F
$FILENAME
$LOAD_PATH
$SAFE
$stdin
$stdout
$stderr
Ruby
$VERBOSE
$- x
$-0
$-a
$-d
$-F
$-i
$-I
$-l
$-p
$_
$~
$&
Ruby
$`
$'
$+
414
Ruby
Description
TRUE
FALSE
NIL
ARGF
ARGV
DATA
ENV
A
hash-like
object containing the
program's
environment variables. ENV can be handled as a hash.
RUBY_PLATFORM
A string indicating
interpreter.
RUBY_RELEASE_DATE
RUBY_VERSION
the
platform
of
the
Ruby
415
Ruby
STDERR
Standard
$stderr.
STDIN
STDOUT
TOPLEVEL_BINDING
error
output
stream.
Default
value
of
416
Ruby
RubyGems:
RubyGems is a package utility for Ruby, which installs Ruby software
packages and keeps them up-to-date.
Ruby Debugger:
To help deal with bugs, the standard distribution of Ruby includes a
debugger. This is very similar to gdb utility, which can be used to debug
complex programs.
Ruby Profiler:
Ruby profiler helps you to improve the performance of a slow program by
finding the bottleneck.
RubyGems
RubyGems is a package utility for Ruby, which installs Ruby software packages
and keeps them up-to-date.
Usage Syntax
$ gem command [arguments...] [options...]
Example
Check to see whether RubyGems is installed:
$ gem --version
0.9.0
417
Ruby
RubyGems Commands
Here is a list of all important commands for RubyGems:
SN
build
Builds a gem from a gemspec.
cert
Adjusts RubyGems certificate settings.
check
Checks installed gems.
cleanup
Cleans up old versions of installed gems in the local repository.
contents
Displays the contents of the installed gems.
dependency
Shows the dependencies of an installed gem.
environment
Displays RubyGems environmental information.
help
Provides help on the 'gem' command.
install
Installs a gem into the local repository.
10
list
Displays all gems whose name starts with STRING.
11
query
Queries gem information in local or remote repositories.
12
rdoc
Generates RDoc for pre-installed gems.
13
search
Displays all gems whose name contains STRING.
418
Ruby
14
specification
Displays gem specification (in yaml).
15
uninstall
Uninstalls a gem from the local repository.
16
unpack
Unpacks an installed gem to the current directory.
17
update
Updates the named gem (or all installed gems) in the local repository.
--source URL
Uses URL as the remote source for gems.
-h, --help
Gets help on this command.
--config-file FILE
Uses this config file instead of default.
--backtrace
Shows stack backtrace on errors.
--debug
Turns on Ruby debugging.
419
Ruby
SN
-l, --local
Restricts operations to the LOCAL domain (default).
-r, --remote
Restricts operations to the REMOTE domain.
-b, --both
Allows LOCAL and REMOTE operations.
-d, --[no-]rdoc
Generates RDoc documentation for the gem on install.
-f, --[no-]force
Forces gem to install, bypassing dependency checks.
-t, --[no-]test
Runs unit tests prior to installation.
-w, --[no-]wrappers
Uses bin wrappers for executables.
10
11
--ignore-dependencies
Do not install any required dependent gems.
12
-y, --include-dependencies
Unconditionally installs the required dependent gems.
Examples
This will install 'SOAP4R', either from local directory or remote server including
all the dependencies:
gem install soap4r --include-dependencies
420
Ruby
Further Readings
The RubyGems User Guide gives you almost everything you need to
know about using RubyGems.
Ruby Debugger
It doesn't matter how easy a language is to use, it usually contains some bugs if
it is more than a few lines long. To help deal with bugs, the standard distribution
of Ruby includes a debugger.
In order to start the Ruby debugger, load the debug library using the commandline option -r debug. The debugger stops before the first line of executable code
and asks for the input of user commands.
Usage Syntax
Here is the usage syntax to use ruby debugger:
$ ruby -r debug filename[, ...]
421
Ruby
wat[ch] expression
Sets watchpoints.
cat[ch] (exception|off)
Sets catchpoint to an exception.
b[reak]
Displays breakpoints and watchpoints.
del[ete] [n]
Deletes breakpoints.
disp[lay] expression
Displays value of expression.
undisp[lay] [ n]
Removes display of n.
c[ont]
Continues execution.
s[tep] [ n]
Executes next n lines stepping into methods.
10
n[ext] [ n]
Executes next n lines stepping over methods.
11
w[here]
Displays stack frame.
12
f[rame]
Synonym for where.
13
l[ist][<-| n- m>]
422
Ruby
up [ n]
Moves up n levels in the stack frame.
15
down [ n]
Moves down n levels in the stack frame.
16
fin[ish]
Finishes execution of the current method.
17
tr[ace] [on|off]
Toggles trace mode on and off.
18
q[uit]
Exits debugger.
19
v[ar] g[lobal]
Displays global variables.
20
v[ar] l[ocal]
Displays local variables.
21
22
23
24
Ruby
25
th[read] l[ist]
Displays threads.
26
th[read] c[ur[rent]]
Displays current thread.
27
th[read] n
Stops specified thread.
28
29
30
31
p expression
Evaluates the expression.
32
h[elp]
Displays help message.
33
everything else
Evaluates.
Example
Consider the following file hello.rb, which needs to be debugged:
#!/usr/bin/env ruby
class Hello
def initialize( hello )
@hello = hello
424
Ruby
end
def hello
@hello
end
end
hello.rb:3:class Hello
(rdb:1) v l
salute => nil
(rdb:1) b 10
Set breakpoint 1 at hello.rb:10
(rdb:1) c
Hello, Mac!
[root@ruby]#
Interactive Ruby
Interactive Ruby or irb is an interactive programming environment that comes
with Ruby. It was written by Keiju Ishitsuka.
Usage Syntax
To invoke it, type irb at a shell or command prompt, and begin entering Ruby
statements and expressions. Use exit or quit to exit irb.
$ irb[.rb] [options] [programfile] [arguments]
425
Ruby
-m
bc mode (load mathn library so fractions or matrix are available).
-d
Sets $DEBUG to true (same as ruby -d).
-r load-module
Same as ruby -r.
-I path
Specifies $LOAD_PATH directory.
--inspect
Uses inspect for output (default except for bc mode).
--noinspect
Doesn't use inspect for output.
--readline
Uses Readline extension module.
--noreadline
Doesn't use Readline extension module.
10
Ruby
11
--inf-ruby-mode
Uses prompt appropriate for inf-ruby-mode on Emacs. Suppresses -readline.
12
--simple-prompt
Simple prompt mode.
13
--noprompt
No prompt mode.
14
--tracer
Displays trace for each execution of commands.
15
--back-trace-limit n
Displays backtrace top n and tail n. The default value is 16.
16
--irb_debug n
Sets internal debug level to n (not for popular use).
17
-v (--version).
Prints the version of irb.
Example
Here is a sample of irb evaluating a variety of expressions::
$ irb
irb(main):001:0> 23 + 27
=> 50
irb(main):002:0> 50 - 23
=> 27
irb(main):003:0> 10 * 5
=> 50
irb(main):004:0> 10**5
=> 100000
irb(main):006:0> x = 1
427
Ruby
=> 1
irb(main):007:0> x + 59
=> 60
irb(main):005:0> 50 / 5
=> 10
irb(main):008:0> hi = "Hello, Mac!"
=> "Hello, Mac!"
You can also invoke a single program with irb. After running the program, irb
exits. Let's call our hello.rb program:
$ irb hello.rb
hello.rb(main):001:0> #!/usr/bin/env ruby
hello.rb(main):002:0*
hello.rb(main):003:0* class Hello
hello.rb(main):004:1> def initialize( hello )
hello.rb(main):005:2> @hello = hello
hello.rb(main):006:2> end
hello.rb(main):007:1> def hello
hello.rb(main):008:2> @hello
hello.rb(main):009:2> end
hello.rb(main):010:1> end
=> nil
hello.rb(main):011:0>
hello.rb(main):012:0* salute = Hello.new( "Hello, Mac!" )
=> #<Hello:0x319f20 @hello="Hello, Mac!">
hello.rb(main):013:0> puts salute.hello
Hello, Mac!
=> nil
hello.rb(main):014:0> $
Ruby Profiler
In most cases, you can improve the performance of a slow program by removing
the bottleneck. The profiler is a tool that finds the bottleneck.
428
Ruby
In order to add profiling to your Ruby program, you need to first load the Profile
library using the command-line option -r profile.
Usage Syntax
$ ruby -r profile [programfile] [arguments]
Example
Here is the output generated from hello.rb file but this would not give you much
idea so, you can try using a bigger program. Output is shown with small font.
[root@ruby]# ruby -r profile hello.rb
Hello, Mac!
%
cumulative
self
time
seconds
seconds
0.00
0.00
0.00
0.00
Module#method_added
self
total
calls
ms/call
ms/call
0.00
0.00
0.00
0.00
0.00
0.00
name
IO#write
0.00
0.00
0.00
0.00
0.00
Hello#hello
0.00
0.00
0.00
0.00
0.00
Hello#initialize
0.00
0.00
0.00
0.00
0.00
Class#inherited
0.00
0.00
0.00
0.00
0.00
Kernel.puts
0.00
0.00
0.00
0.00
0.00
Class#new
0.00
0.01
0.00
0.00
10.00
#toplevel
429
Ruby
Syntax
Here is a syntax to write single line of eRuby code:
<% ruby code %>
They function like blocks in Ruby and are terminated by <% end %>.
<ul>
<% 3.times do %>
<li>list item</li>
Example
Here's a sample eRuby file:
This is sample eRuby file<br>
The current time here is <%=Time.now%>.
<%[1,2,3].each{|x|print x,"<br>\n"}%>
Ruby
1
2
3
For complete details on eRuby, refer to eRuby Home.
Usage Syntax
Here is simple syntax to use ri
ri [ options ] [ methodname... ]
Here is a complete list of options:
SN
--version,
-v
Displays version and exits.
--line-length=n
-l n
Sets the line length for the output (minimum is 30 characters).
--synopsis
-s
Displays just a synopsis.
--format= name
-f name
Uses the name module (default is Plain) for output formatting. Here are
the available modules:
Tagged: Simple tagged output
431
Ruby
432