Ruby Tutorial
Ruby Tutorial
Ruby tutorial provides basic and advanced concepts of Ruby. Our Ruby programming
tutorial is designed for beginners and professionals both.
Our Ruby tutorial includes all topics of Ruby such as installation, example, operators,
control statements, loops, comments, arrays, strings, hashes, regular expressions; file
handling, exception handling, OOPs, Ranges, Iterators. Etc
Ruby Tutorial
Ruby Tutorial
What is Ruby
Ruby Features
Ruby vs Python
Ruby Installation
Hello Ruby Program
Ruby Operators
Ruby Variables
Ruby Data Types
What is Ruby
Ruby is a dynamic, open source, object oriented and reflective programming language.
Ruby is considered similar to Perl and Smalltalk programming languages. It runs on all
types of platforms like Windows, Mac OS and all versions of UNIX.
It means that the language behaves in such a way to minimize the confusion for
experienced users.
History of Ruby
Ruby is designed and developed by Yukihiro "Martz" Matsumoto in mid 1990s in Japan.
Idea of Ruby
Perl is a scripting language but comes under the category of Toy language. Python is
not fully object oriented language. Ruby developer Yukihiro "Martz" Matsumoto wanted
a programming language which is completely object oriented and should be easy to
use as a scripting language. He searched for this type of language, but couldn't find
one. Hence, he developed on
Ruby 1.8.7 was released in May 2008. At this point, Ruby was at its peak so much that
even MacOS X began their shipping with built-in Ruby.
Ruby in Present
The current Ruby version 2.4.0 was released on Christmas in 2016. It has several new
features like improvement to hash table, instance variable access, Array #max and
Array #min.
Future of Ruby
Ruby is a great object oriented scripting programming language. Looking at its past we
can say that it has a bright future if its community members continue expanding it
beyond the thinking.
Ruby Versions
There are many Ruby versions that have been released till date. Current stable Ruby
version is 2.4
Object Oriented
Ruby is purely object oriented programming language. Each and every value is an
object. Every object has a class and every class has a super class. Every code has their
properties and actions. Ruby is influenced with Smalltalk language. Rules applying to
objects applies to the entire Ruby.
Flexibility
Ruby is a flexible language as you can easily remove, redefine or add existing parts to it.
It allows its users to freely alter its parts as they wish.
Mixins
Ruby has a feature of single inheritance only. Ruby has classes as well as modules. A
module has methods but no instances. Instead, a module can be mixed into a class,
which adds the method of that module to the class. It is similar to inheritance but much
more flexible
Visual appearance
Ruby generally prefers English keyword and some punctuation is used to decorate
Ruby. It doesn't need variable declaration
Ruby variables are loosely typed language, which means any variable can hold any type
of object. When a method is called on an object, Ruby only looks up at the name
irrespective of the type of object. This is duck typing. It allows you to make classes that
pretend to be other classes.
Variable constants
In Ruby, constants are not really constant. If an already initialized constant will be
modified in a script, it will simply trigger a warning but will not halt your program.
Naming conventions
Ruby defines some naming conventions for its variable, method, constant and class.
Constant: Starts with a capital letter.
Global variable: Starts with a dollar sign ($).
Instance variable: Starts with a (@) sign.
Class variable: Starts with a (@@) sign.
Method name: Allowed to start with a capital letter.
Keyword arguments
Like Python, Ruby methods can also be defined using keyword arguments
Method names
Methods are allowed to end with question mark (?) or exclamation mark (!). By
convention, methods that answer questions end with question mark and methods that
indicate that method can change the state of the object end with exclamation mark.
Singleton methods
Ruby singleton methods are per-object methods. They are only available on the object
you defined it on.
Missing method
If a method is lost, Ruby calls the method_missing method with name of the lost
method
Statement delimiters
Multiple statements in a single line must contain semi colon in between but not at the
end of a line.
Keywords
In Ruby there are approximately 42 keywords which can't be used for other purposes.
They are called reserved words.
Case Sensitive
Ruby is a case-sensitive language. Lowercase letters and uppercase letters are different
Ruby vs Python
There are many differences and similarities between Ruby and Python programming
language.
Similarities
1. They both are high level language.
2. They both are server side scripting language.
3. Both are used for web applications.
4. Both work on multiple platforms.
5. Both have clean syntax and are easily readable.
6. Both use an interactive prompt called irb.
7. Objects are strongly and dynamically typed.
8. Both use embedded doc tools.
Differences
Terms Ruby Python
Definition Ruby is an open source web Python is a high level
application programming programming language.
language.
Object Oriented Fully object oriented Not fully object oriented
programming language programming language
Developer Yukihiro Matsumoto in 1990s. Guido Van Rossum in
1980s.
Developing Eclipse IDE is supported multiple IDEs are supported
Environment
Libraries Libraries It has smaller library Has larger range of
than Python. libraries
Mixins Mixins are used. Mixins can't be used.
Ruby Installation
Ruby is a cross platform programming language. It is installed differently on different
operating systems.
1. For UNIX like operating system, use your system's package manager.
2. For Windows operating system, use Ruby Installer.
3. For OS X system, use third party tools (rbenv and RVM).
Step 1 Choose the package management system which you want to install.
Step 2 Debian GNU/Linux and Ubuntu use the apt package manager. Use the following
command
Here, by default, the ruby-full package provides Ruby 1.9.3 version which is an old
version onDebian and Ubuntu.
Step 3 To know your Ruby version installed in your system, use the command,
ruby -v
2) Connect Ruby path to the above file. We have created hello.rb file in the Desktop. So
first we need to go the Desktop directory through our console
ruby hello.rb
Ruby Operators
Ruby has a built-in modern set of operators. Operators are a symbol which is used to
performdifferent operations. For example, +, -, /, *, etc.
Types of operators:
Unary operator
Arithmetic operator
Bitwise operator
Logical operator
Ternary operator
Assignment operator
Comparison operator
Range operator
Unary Operator
Unary operators expect a single operand to run on.
Operator Description
! Boolean NOT
~ Bitwise complement
+ Unary plus
puts("Unary operator")
puts(~5)
puts(~-5)
puts(!true)
puts(!false)
Output:
Arithmetic Operator
Arithmetic operators take numerical values as operands and return them in a single
value
Operator Description
+ Adds values from both sides of the operator.
- Subtract values from both sides of the operator.
/ Divide left side operand with right side
operand.
* Multiply values from both sides of the operator.
** Right side operand becomes the exponent of
left side operand.
% Divide left side operand with right side operand
returning remainder.
Output:
Bitwise Operator
Bitwise operators work on bits operands
Operator Description
Logical Operator
Logical operators work on bits operands.
Operator Description
&& AND operator
|| OR operator
Ternary Operator
Ternary operators first check whether given conditions are true or false, then execute
the condition.
Operator Description
?: Conditional expression
#!/usr/bin/ruby -w
puts("Ternary operator")
puts(2<5 ? 5:2)
puts(5<2 ? 5:2)
Output:
Assignment Operator
Assignment operator assigns a value to the operands.
Operator Description
= Simple assignment operator
+= Add assignment operator
-= subtract assignment operator
*= Multiply assignment operator
/= Divide assignment operator
%= Modulus assignment operator
**= Exponential assignment operator
Comparison Operator
Comparison operators compare two operands.
Operator Description
== Equal operator
!= Not equal operator
> left operand is greater than right operand
< Right operand is greater than left operand
>= Left operand is greater than or equal to right operand
Output:
Range Operator
Range operators create a range of successive values consisting of a start, end and range
of values in between
The (..) creates a range including the last term and (...) creates a range excluding the last
term.
For example, for the range of 1..5, output will range from 1 to 5. and for the range of
1...5, output will range from 1 to 4.
Operator Description
.. Range is inclusive of the last term
... Range is exclusive of the last term
Ruby Variables
Ruby variables are locations which hold data to be used in the programs. Each variable
has a different name. These variable names are based on some naming conventions.
Unlike other programming languages, there is no need to declare a variable in Ruby. A
prefix is needed to indicate it. There are four types of variables in Ruby:
When uninitialized local variables are called, they are interpreted as call to a method
that has no arguments.
Class variables
A class variable name starts with @@ sign. They need to be initialized before use. A
class variable belongs to the whole class and can be accessible from anywhere inside
the class. If the value will be changed at one instance, it will be changed at every
instance. A class variable is shared by all the descendent of the class. An uninitialized
class variable will result in an error.
#!/usr/bin/ruby
class States
@@no_of_states=0
def initialize(name)
@states_name=name
@@no_of_states += 1
end
def display()
puts "State name #@state_name"
end
def total_no_of_states()
puts "Total number of states written: #@@no_of_states"
end
end
# Create Objects
first=States.new("Assam")
second=States.new("Meghalaya")
third=States.new("Maharashtra")
fourth=States.new("Pondicherry")
# Call Methods
first.total_no_of_states()
second.total_no_of_states()
third.total_no_of_states()
fourth.total_no_of_states()
In the above example, @@no_of_states is a class variable.
Output:
Instance variables
An instance variable name starts with a @ sign. It belongs to one instance of the class
and can be accessed from any instance of the class within a method. They only have
limited access to a particular instance of a class.
They don't need to be initialized. An uninitialized instance variable will have a nil value.
Example:
#!/usr/bin/ruby
class States
def initialize(name)
@states_name=name
end
def display()
puts "States name #@states_name"
end
end
# Create Objects
First=States.new("Assam")
Second=States.new("Meghalaya")
Third=States.new("Maharashtra")
Fourth=States.new("Pondicherry")
# Call Methods
first.display()
second.display()
third.display()
fourth.display()
An uninitialized global variable will have a nil value. It is advised not to use them as they
make programs cryptic and complex. There are a number of predefined global variables
in Ruby.
Example:
#!/usr/bin/ruby
$global_var = "GLOBAL"
class One
def display
puts "Global variable in One is #$global_var"
end
end
class Two
def display
puts "Global variable in Two is #$global_var"
end
end
oneobj = One.new
oneobj.display
twoobj = Two.new
twoobj.display
Output:
Summary
Local Global Instance Class
Scope Limited within the Its scope is It belongs to Limited to the
block of initialization. globally. one instance of whole class in
a class. which they are
created.
Naming Starts with a lower Starts with a $ Starts with an@ Starts with an
case letter or sign. sign. @@sign.
underscore (_).
Initialization No need to initialize. No need to No need to They need to be
An uninitialized local initialize. An initialize. An initialized before
variable is interpreted uninitialized uninitialized use. An
as methods with no global instance variable uninitialized
arguments. variable will will have a nil global variable
have a nil value. results in an error.
value.
Numbers
Strings
Symbols
Hashes
Arrays
Booleans
Numbers
Integers and floating point numbers come in the category of numbers.
Integers are held internally in binary form. Integer numbers are numbers without a
fraction.
According to their size, there are two types of integers. One is Bignum and other is
Fixnum.
Example:
In a calculation if integers are used, then only integers will be returned back
In a calculation if float type is used, then only float will be returned back.
Example:
Two strings can be concatenated using + sign in between them.
Multiplying a number string with a number will repeat the string as many times
Symbols
Symbols are like strings. A symbol is preceded by a colon (:). For example,
:abcd
They do not contain spaces. Symbols containing multiple words are written with (_). One
difference between string and symbol is that, if text is a data then it is a string but if it is
a code it is a symbol.
Symbols are unique identifiers and represent static values, while string represent values
that change.
Example:
In the above snapshot, two different object_id is created for string but for symbol same
object_id is created.
Hashes
A hash assigns its values to its keys. They can be looked up by their keys. Value to a key
is assigned by => sign. A key/value pair is separated with a comma between them and
all the pairs are enclosed within curly braces. For example, 10/28/21, 12:42 AM Ruby
Data Types :
Example:
#!/usr/bin/ruby
data = {"Akash" => "Physics", "Ankit" => "Chemistry", "Aman" => "Maths"}
puts data["Akash"]
puts data["Ankit"]
puts data["Aman"]
Output:
Arrays
An array stores data or list of data. It can contain all types of data. Data in an array are
separated by comma in between them and are enclosed by square bracket.
For example,
["Akash", "Ankit", "Aman"]
Elements from an array are retrieved by their position. The position of elements in an
array starts with 0.
Example:
#!/usr/bin/ruby
data = ["Akash", "Ankit", "Aman"]
puts data[0]
puts data[1]
puts data[2]
Output:
Ruby if statement
Ruby if statement tests the condition. The if block statement is executed if condition is
true.
Syntax:
if (condition)
//code to be executed
end
Example:
a = gets.chomp.to_i
if a >= 18
puts "You are eligible to vote."
end
Output:
Ruby if else
Ruby if else statement tests the condition. The, if block statement is executed if
condition is true otherwise else block statement is executed.
Syntax:
if(condition)
//code if condition is true
else
//code if condition is false
end
Example:
a = gets.chomp.to_i
if a >= 18
puts "You are eligible to vote."
else
puts "You are not eligible to vote."
end
Output:
Syntax:
if(condition1)
//code to be executed if condition1is true
elsif (condition2)
//code to be executed if condition2 is true
else (condition3)
//code to be executed if condition3 is true
end
Example:
a = gets.chomp.to_i
if a <50
puts "Student is fail"
elsif a >= 50 && a <= 60
puts "Student gets D grade"
elsif a >= 70 && a <= 80
puts "Student gets B grade"
elsif a >= 80 && a <= 90
puts "Student gets A grade"
elsif a >= 90 && a <= 100
puts "Student gets A+ grade"
end
Output:
Syntax:
test-expression ? if-true-expression : if-false-expression
Example:
var = gets.chomp.to_i;
a = (var > 3 ? true : false);
puts a
Output:
Syntax:
case expression
[when expression [, expression ...] [then]
code ]...
[else
code ]
end
Example:
#!/usr/bin/ruby
print "Enter your day: "
day = gets.chomp
case day
when "Tuesday"
puts 'Wear Red or Orange'
when "Wednesday"
puts 'Wear Green'
when "Thursday"
puts 'Wear Yellow'
when "Friday"
puts 'Wear White'
when "Saturday"
puts 'Wear Black'
else
puts "Wear Any color"
end
Output:
Look at the above output, conditions are case sensitive. Hence, the output for 'Saturday'
and 'saturday' are different
Syntax:
for variable [, variable ...] in expression [do]
code
end
Output:
Output:
Ruby while Loop
The Ruby while loop is used to iterate a program several times. If the number of
iterations is not fixed for a program, while loop is used. Ruby while loop executes a
condition while a condition is true. Once the condition becomes false, while loop stops
its execution.
Syntax:
while conditional [do]
code
end
Example:
#!/usr/bin/ruby
x = gets.chomp.to_i
while x >= 0
puts x
x -=1
end
Output:
Syntax:
loop do
#code to be executed
break if booleanExpression
end
Example:
loop do
puts "Checking for answer"
answer = gets.chomp
if answer != '5'
break
end
end
Output:
Syntax:
until conditional
code
end
Example:
i=1
until i == 10
print i*10, "\n"
i += 1
end
Output:
Syntax:
break
Example:
i=1
while true
if i*5 >= 25
break
end
puts i*5
i += 1
end
Output:
Syntax:
next
Example:
for i in 5...11
if i == 7 then
next
end puts i end
Output:
Syntax:
redo
Example:
i=0
while(i < 5) # Prints "012345" instead of "01234"
puts i
i += 1
redo if i == 5
end
Output:
Syntax:
retry
Ruby Comments
Ruby comments are non-executable lines in a program. These lines are ignored by the
interpreterhence they don't execute while execution of a program. They are written by a
programmer toexplain their code so that others who look at the code will understand it
in a better way. Types of Ruby comments:
Single line comment
multi line comment
Output:
The Ruby multi line comment is used to comment multiple lines at a time. They are
defined with=begin at the starting and =end at the end of the line.
Syntax:
=begin
This
is
multi line
comment
=end
Example:
=begin
we are declaring
a variable i in this program
=end
i = 10 puts i
Output:
Ruby Class and Object
Here, we will learn about Ruby objects and classes. In object-oriented programming
language, we design programs using objects and classes. Object is a physical as well as
logical entity whereas class is a logical entity only.
Ruby Object
Object is the default root of all Ruby objects. Ruby objects inherit from BasicObject (it
is the parent class of all classes in Ruby) which allows creating alternate object
hierarchies. Object mixes in the Kernel module which makes the built-in Kernel
functions globally accessible.
Creating object
Objects in Ruby are created by calling new method of the class. It is a unique type of
method and predefined in the Ruby library. Ruby objects are instances of the class.
Syntax:
objectName = className.new
Example:
We have a class named Java. Now, let's create an object java and use it with following
command,
java = Java.new("John")
Output:
Ruby Class
Each Ruby class is an instance of class Class. Classes in Ruby are first-class objects.
Ruby class always starts with the keyword class followed by the class name.
Conventionally, for class name we use Camel Case. The class name should always start
with a capital letter. Defining class is finished with end keyword.
Syntax:
class ClassName
codes...
end
Example
Ruby Methods
Ruby methods prevent us from writing the same code in a program again and again. It
is a set of expression that returns a value.
Ruby methods are similar to the functions in other languages. They unite one or more
repeatable statements into one single bundle.
Defining Method
To use a method, we need to first define it. Ruby method is defined with the def
keyword followed by method name. At the end we need to use end keyword to denote
that method has been defined.
Methods name should always start with a lowercase letter. Otherwise, it may be
misunderstood as a constant.
Syntax:
def methodName
code...
end
Example:
Here, we have defined a method welcome using def keyword. The last line end keyword
says that we are done with the method defining. Now let's call this method. A method is
called by just writing its name
Here, #{name} is a way in Ruby to insert something into string. The bit inside the braces
is turnedinto a string.
Ruby Blocks
Ruby code blocks are called closures in other programming languages. It consist of a
group of codes which is always enclosed with braces or written between do..end. The
braces syntax always have the higher precedence over the do..end syntax. Braces have
high precedence and do has low precedence.
A block is written in two ways,
Multi-line between do and end (multi-line blocks are niot inline)
Inline between braces {}
Syntax:
block_name{
statement1 statement2 .......... }
Example:
The below example shows the multi-line block.
[10, 20, 30].each do |n|
puts n
end
Output:
Output:
The yield statement
The yield statement is used to call a block within a method with a value.
Example:
#!/usr/bin/ruby
def met
puts "This is method"
yield
puts "You will be back to method"
yield
end
met {puts "This is block"}
Output:
While the execution of met method, when we reach at yield line, the code inside the
block isexecuted. When block execution finishes, code for met method continues.
Example:
#!/usr/bin/ruby
def met
yield 1
puts "This is method"
yield 2
end
met {|i| puts "This is block #{i}"}
Output:
Block Variables
We can use same variable outside and inside a block parameter. Let's see the following
example.
Example:
#!/usr/bin/ruby
x = "Outer variable"
3.times do |x|
puts "Inside the block: #{x}" end
puts "Outside the block: #{x}"
In this example, we are using same variable inside the block as the block parameter x
and outside the block as a variable x.
Example:
#!/usr/bin/ruby
BEGIN {
puts "code block is being loaded"
}
END {
puts "code block has been loaded"
}
puts "This is the code block"
Output:
Here, block word after the & is just a name for the reference, any other name can be
used instead of this.
Example:
def met(&block)
puts "This is method"
block.call
end
met { puts "This is &block example" }
Output:
Here, the block variable inside method met is a reference to the block. It is executed
with the call method. The call method is same as yield method.
Initializing objects with default values
Ruby has an initializer called yield(self). Here, self is the object being initialized.
Example:
class Novel
def initialize
yield(self)
end
end
Ruby Modules
Ruby module is a collection of methods and constants. A module method may be
instance method or module method.
Module methods may be called without creating an encapsulating object while instance
methods may not.
They are similar to classes as they hold a collection of methods, class definitions,
constants and other modules. They are defined like classes. Objects or subclasses can’t
be created using modules. There is no module hierarchy of inheritance.
Syntax:
module ModuleName
statement1
statement2
...........
end
Module Namespaces
While writing larger files, a lot of reusable codes are generated. These codes are
organized into classes, which can be inserted into a file.
For example, if two persons have the same method name in different files. And both the
files need to be included in a third file. Then it may create a problem as the method
name in both included files is same.
Here, module mechanism comes into play. Modules define a namespace in which you
can define your methods and constants without over riding by other methods and
constants.
Example:
Suppose, in file1.rb, we have defined number of different type of library books like
fiction, horror, etc.
In file2.rb, we have defined the number of novels read and left to read including fiction
novels.
In file3.rb, we need to load both the files file1 and file2. Here we will use module
mechanism.
file1.rb
#!/usr/bin/ruby
# Module defined in file1.rb file
module Library
num_of_books = 300
def Library.fiction(120)
# ..
end
def Library.horror(180)
# ..
end
end
file2.rb
#!/usr/bin/ruby
# Module defined in file2.rb file
module Novel
total = 123
read = 25
def Novel.fiction(left)
# ...
end
file3.rb
require "Library"
require "Novel"
x = Library.fiction(Library::num_of_books)
y = Novel.fiction(Novel::total)
A module method is called by preceding its name with the module's name and a period,
and you reference a constant using the module name and two colons.
Module Mixins
Ruby doesn't support multiple inheritance. Modules eliminate the need of multiple
inheritance using mixin in Ruby.
A module doesn't have instances because it is not a class. However, a module can be
included within a class.
When you include a module within a class, the class will have access to the methods of
the module.
Example:
module Name
def bella
end
def ana
end
end
module Job
def editor
end
def writer
end
end
class Combo
include Name
include Job
def f
end
end
final=Combo.new
final.bella
final.ana
final.editor
final.writer
final.f
Here, module Name consists of methods bella and ana. Module Job consists of
methods editor and writer. The class Combo includes both the modules due to which
class Combo can access all the four methods. Hence, class Combo works as mixin.
The methods of a module that are mixed into a class can either be an instance method
or a class method. It depends upon how you add mixin to the class
Ruby Strings
Ruby string object holds and manipulates an arbitary sequence of bytes, typically
representingcharacters. They are created using String::new or as literals.
Quotes
Ruby string literals are enclosed within single and double quotes.
Example:
!/usr/bin/ruby
puts 'Hello everyone'
puts "Hello everyone"
Output:
Accessing string elements
You can access Ruby string elements in different parts with the help of square brackets
[]. Within square brackets write the index or string.
Example:
#!/usr/bin/ruby
msg = "This tutorial is from JavaTpoint."
puts msg["JavaTpoint"]
puts msg["tutorial"]
puts msg[0]
puts msg[0, 2]
puts msg[0..19]
puts msg[0, msg.length]
puts msg[-3]
Output:
⇧ SCROLL TO TOP
Multiline string
Writing multiline string is very simple in Ruby language. We will show three ways to print multiline string.
String can be written within double quotes.
The % character is used and string is enclosed within / character.
In heredoc syntax, we use << and string is enclosed within word STRING.
Example:
puts "
A
AB
ABC
ABCD"
puts %/
A
AB
ABC
ABCD/
puts <<STRING
A
AB
ABC
ABCD
STRING
Output:
Variable Interpolation
Ruby variable interpolation is replacing variables with values inside string literals. The
variable name is put between #{ and } characters inside string literal.
Example:
#!/usr/bin/ruby
country = "India"
capital = "New Delhi"
puts "#{capital} is the capital of #{country}."
Output:
Concatenating Strings
Ruby concatenating string implies creating one string from multiple strings. You can
join more than one string to form a single string by concatenating them.
There are four ways to concatenate Ruby strings into single string:
Example:
#!/usr/bin/ruby
string = "This is Ruby Tutorial" + " from JavaTpoint." + " Wish you all good luck."
puts string
string = "This is Ruby Tutorial" " from JavaTpoint." " Wish you all good luck."
puts string
string = "This is Ruby Tutorial" << " from JavaTpoint." << " Wish you all good luck."
puts string
string = "This is Ruby Tutorial".concat(" from JavaTpoint.").concat(" Wish you all good
luck.")
puts string
Output:
Freezing Strings
In most programming languages strings are immutable. It means that an existing string
can't be modified, only a new string can be created out of them.
In Ruby, by default strings are not immutable. To make them immutable, freeze method
can be used.
Example:
#!/usr/bin/ruby
str = "Original string"
str << " is modified "
str << "is again modified"
puts str
str.freeze
#str << "And here modification will be failed after using freeze method"
Output:
In the above output, we have made the string immutable by using freeze method.
Last line is commented as no string can't be modified any further
By uncommenting the last line, we'll get an error as shown in the below output.
Comparing Strings
Ruby strings can be compared with three operators:
With == operator : Returns true or false
With eql? Operator : Returns true or false
With case cmp method : Returns 0 if matched or 1 if not matched
Example:
#!/usr/bin/ruby
puts "abc" == "abc"
puts "as ab" == "ab ab"
puts "23" == "32"
puts "ttt".eql? "ttt"
puts "12".eql? "12"
puts "Java".casecmp "Java"
puts "Java".casecmp "java"
puts "Java".casecmp "ja"
Output:
Ruby Arrays
Ruby arrays are ordered collections of objects. They can hold objects like integer,
number, hash,string, symbol or any other array.
Its indexing starts with 0. The negative index starts with -1 from the end of the array.
Forexample, -1 indicates last element of the array and 0 indicates first element of the
array.
For example, following array contains an integer, floating number and a string.
Output:
Syntax:
arrayName = Array.new
Syntax:
arrayName = Array.new(10)
Example:
#!/usr/bin/ruby
exm = Array.new(10)
puts exm.size
puts exm.length
Output:
Example:
#!/usr/bin/ruby
exm = Array("a"..."z")
puts "#{exm}"
Output:
#[] method
Example:
at method
To access a particular element, at method can also be used.
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.at(0)
puts days.at(-1)
puts days.at(5)
Out[put:
slice method
The slice method works similar to #[] method.
fetch method
The fetch method is used to provide a default value error for out of array range indices.
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.fetch(10)
Output:
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.fetch(10, "oops")
Output:
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.first
puts days.last
Output:
take method
The take method returns the first n elements of an array.
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.take(1)
puts days.take(2)
Output:
drop method
The drop method is the opposite of take method. It returns elements after n elements
have been dropped.
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.drop(5)
puts days.drop(6)
Output:
push or <<
Using push or <<, items can be added at the end of an array.
Example:
days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
puts days.push("Today")
puts days << ("Tomorrow")
Output:
unshift
Using unshift, a new element can be added at the beginning of an array.
Example:
days = ["Fri", "Sat", "Sun"]
puts days.unshift("Today")
Output:
Insert
Using insert, a new element can be added at any position in an array. Here, first we need
to mention the index number at which we want to position the element.
Example:
days = ["Fri", "Sat", "Sun"]
puts days.insert(2, "Thursday")
Output:
Removing Items from Array
Ruby array elements can be removed in different ways.
pop
shift
delete
uniq
pop
Using pop, items can be removed from the end of an array. It returns the removed item.
Example:
days = ["Fri", "Sat", "Sun"]
puts days.pop
Output:
shift
Using shift, items can be removed from the start of an array. It returns the removed
item.
Example:
days = ["Fri", "Sat", "Sun"]
puts days.shift
Output:
delete
Using delete, items can be removed from anywhere in an array. It returns the removed
item.
Example:
days = ["Fri", "Sat", "Sun"]
puts days.delete("Sat")
Output:
uniq
Using uniq, duplicate elements can be removed from an array. It returns the remaining
array.
Example:
days = ["Fri", "Sat", "Sun", "Sat"]
puts days.uniq
Output:
Ruby Hashes
A Ruby hash is a collection of unique keys and their values. They are similar to arrays
but arrayuse integer as an index and hash use any object type. They are also called
associative arrays,dictionaries or maps.
If a hash is accessed with a key that does not exist, the method will return nil.
Syntax:
name = {"key1" => "value1", "key2" => "value2", "key3" => "value3"...}
OR
name = {key1: 'value1', key2: 'value2', key3: 'value3'...}
Example:
color = {
"Rose" => "red",
"Lily" => "purple",
"Marigold" => "yellow",
"Jasmine" => "white" }
puts color['Rose']
puts color['Lily']
puts color['Marigold']
puts color['Jasmine']
Output:
Example:
color = {
"Rose" => "red",
"Lily" => "purple",
"Marigold" => "yellow",
"Jasmine" => "white" }
color['Tulip'] = "pink"
color.each do |key, value|
puts "#{key} color is #{value}"
end
Output:
Method Description
hsh==other_hash Two hashes are equal if they contain same key and value
pair.
hsh[key] Retrieve value from the respective key.
Date
Date &Time
Time
Date
Ruby date provides two classes, Date and Date &Time.
The Date object is created with ::new, ::parse, ::today, ::jd, ::strptime, etc. All date objects
are immutable, hence they can't modify themselves.
Example:
require 'date'
puts Date.new(2017,4,3)
puts Date.jd(2451877)
puts Date.ordinal(2017,3)
puts Date.commercial(2017,5,6)
puts Date.parse('2017-02-03')
puts Date.strptime('03-02-2017', '%d-%m-%Y')
puts Time.new(2017,10,8).to_date
Output:
The Date object has various methods as shown in the below example.
Example:
require 'date'
d = Date.parse('4th Mar 2017')
puts d.year
puts d.mon
puts d.mday
puts d.wday
puts d += 1
puts d.strftime('%a %d %b %Y')
Output:
DateTime
Ruby DateTime is a subclass of Date. It easily handles date, hour, minute, second and
offset.
Example:
require 'date'
puts DateTime.new(2017,3,4,5,6,7)
Output:
Example:
require 'date'
d = DateTime.parse('4th Mar 2017 02:37:05+05:40')
puts d.hour
puts d.min
puts d.sec
puts d.offset
puts d.zone
puts d += Rational('1.0')
puts d = d.new_offset('+05:00')
puts d.strftime('%I:%M:%S %p')
puts d > DateTime.new(2000)
Output:
Time
Time class is an abstraction of dates and times. It is stored internally as the number of
seconds since Epoch time. The Time class treats GMT (Grenwich Mean Time) and UTC
(Coordinated Universal Time) equivalent.
Times may appear equal but on comparison they may be different as all times may have
fraction. Time implementation uses a signed 63 bit integer, Bignum or Rational. Time
works slower when integer is used.
While creating a new time instance, you need to pass at least a year. If only year is
passed, then time will default to January 1 of that year at 00:00:00 with current system
time zone.
Example:
puts Time.new
puts Time.new(2017, 3)
puts Time.new(2017, 3, 4)
puts Time.new(2017, 3, 4, 6, 5, 5, "+05:00")
Output:
Example:
puts Time.local(2017, 2, 5)
puts Time.local(2017, 2, 5, 4, 30)
puts Time.utc(2017, 2, 5, 4, 30)
puts Time.gm(2017, 2, 5, 4, 30, 36)
Output:
Working with an instance of time
After creating an instance of time, we can work on that time in following ways.
Example:
t = Time.new(1991, 07, 5, 9, 15, 33, "+09:00")
puts t.friday? #=> false
puts t.year #=> 1993
puts t.dst? #=> false
puts t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
puts t.to_i #=> 730522800
t1 = Time.new(2017)
t2 = Time.new(2015)
puts t1 == t2 #=> false
puts t1 == t1 #=> true
puts t1 < t2 #=> true
puts t1 > t2 #=> false
puts Time.new(2010,10,31).between?(t1, t2) #=> true
Output:
Example:
time = Time.new puts time.zone
puts time.utc_offset puts time.zone
puts time.isdst puts time.utc?
puts time.localtime puts time.gmtime
puts time.getlocal puts time.getutc
Output:
Ruby Ranges
Ruby range represents a set of values with a beginning and an end. They can be
constructed using s..e and s...e literals or with ::new.
The ranges which has .. in them, run from beginning to end inclusively. The ranges
which have ... in them, runs exclusively the end value.
Exemple:
puts (-5..-1).to_a
puts (-5...-1).to_a
puts ('a'..'e').to_a
puts ('a'...'e').to_a
Output:
Ruby has a variety of ways to define ranges.
Ranges as sequences
Ranges as conditions
Ranges as intervals
Ranges as Sequences
The most natural way to define a range is in sequence. They have a start point and an
end point. They are created using either.. or ... operators.
We are taking a sample range from 0 to 5. The following operations are performed on
this range.
Example:
#!/usr/bin/ruby
range = 0..5
puts range.include?(3)
ans = range.min
puts "Minimum value is #{ans}"
ans = range.max
puts "Maximum value is #{ans}"
ans = range.reject {|i| i < 5 }
puts "Rejected values are #{ans}"
range.each do |digit|
puts "In Loop #{digit}"
end
Output:
Ranges as Conditions
Ranges are also defined as conditional expressions. Different conditions are defined in a
set oflines. These conditions are enclosed within start statement and end statement.
Example:
#!/usr/bin/ruby
budget = 50000
watch = case budget
when 100..1000 then "Local"
when 1000..10000 then "Titan"
when 5000..30000 then "Fossil"
when 30000..100000 then "Rolex"
else "No stock"
end
puts watch
Output:
Ranges as Intervals
Ranges can also be defined in terms of intervals. Intervals are represented by === case equalityoperator.
Example:
#!/usr/bin/ruby
if (('a'..'z') === 'v')
puts "v lies in the above range"
end
if (('50'..'90') === 99)
puts "z lies in the above range"
end
Output:
Example:
#!/usr/bin/ruby
puts (5..1).to_a
Nothing will be returned in the output for the above example.
To print a reverse order, you can use reverse method in a normal range as shown below.
Example:
#!/usr/bin/ruby
puts (1..5).to_a.reverse
Output:
Ruby Iterators
Iterator is a concept used in object-oriented language. Iteration means doing one thing manytimes like a
loop.
The loop method is the simplest iterator. They return all the elements from a collection, one afterthe other.
Arrays and hashes come in the category of collection.
Syntax:
(collection).each do |variable|
code...
end
Here collection can be any array, range or hash.
Example:
#!/usr/bin/ruby
(1...5).each do |i|
puts i
end
Output:
Syntax:
x.times do |variable|
code...
end
Output:
Ruby Upto and Downto Iterators
An upto iterator iterates from number x to number y.
Syntax:
x.upto(y) do |variable|
code
end
Example:
#!/usr/bin/ruby
1.upto(5) do |n|
puts n
end
Output:
Syntax:
(controller).step(x) do |variable|
code
end
Example:
#!/usr/bin/ruby
(10..50).step(5) do |n|
puts n
end
Output:
Example:
#!/usr/bin/ruby
"All\nthe\nwords\nare\nprinted\nin\na\nnew\line.".each_line do |line|
puts line
end
Output:
IO has a subclass as File class which allows reading and writing files in Ruby. The two
classes areclosely associated. IO object represent readable/writable interactions to
keyboards and screens.
IO Console
The IO console provides different methods to interact with console. The class IO
provides following basic methods:
IO::console
IO#raw#raw!
IO#cooked
IO#cooked!
IO#getch
IO#echo=
IO#echo?
IO#noecho
IO#winsize
IO#winsize=
IO#iflush
IO#ioflush
IO#oflush
File.open method : Using this method a new file object is created. That file object
isassigned to a file.
Difference between both the methods is that File.open method can be associated with a
blockwhile File.new method can't.
Syntax:
f = File.new("fileName.rb") Or,
File.open("fileName.rb", "mode") do |f|
Step 1) In file hello.rb, write the code to create a new file as shown below.
#!/usr/bin/ruby
File.open('about', 'w') do |f|
f.puts "This is JavaTpoint"
f.write "You are reading Ruby tutorial.\n"
f << "Please visit our website.\n"
end
Step 2) Type the following two commands in the console to view the created file.
ruby hello.rb
cat about
The new file is created and content is displayed in the terminal as shown above.
Syntax:
f.gets
code...
To return the whole file after the current position, following syntax is used.
Syntax:
f.read
code...
Syntax:
f.readlines
[code...]
Step 1) In file hello.rb, write the code to read an already existing file as shown below.
#!/usr/bin/ruby
while line = gets
puts line
end
Step 2) Type the following command in the console to read the file.
ruby hello.rb about
Example:
In file hello.rb, write the code to read an already existing file as shown below.
#!/usr/bin/ruby
aFile = File.new("about.txt", "r")
if aFile
content = aFile.sysread(40)
puts content
else
puts "Unable to open file!"
end
Output:
Output:
Syntax:
File.rename("olderName.txt", "newName.txt")
Example:
#!/usr/bin/ruby
File.rename("about.txt", "new.txt")
Output:
In the above output, about.txt file no longer exist as its name has been changed to
new.txt file. To delete a file, following syntax is used.
Syntax:
File.delete("filename.txt")
Example:
#!/usr/bin/ruby
File.delete("new.txt")
Output:
Ruby Directories
Class Dir has directory streams as objects which represents directories in underlying file
system. Directories are handled with Dir class.
Creating a Directory
To create a directory mkdir command is used. You can give permission to a directory if
you want.
Syntax:
Dir.mkdir "dirName" , permission
Example:
Dir.mkdir "project"
We have created a directory "project" in our system.
Syntax:
puts Dir.exists? "dirName"
Example:
#!/usr/bin/ruby
puts Dir.exists? "project"
puts Dir.exists? "pproject"
Output:
the correct directory name display true and wrong directory name display false.
Syntax:
puts Dir.pwd
Example:
puts Dir.pwd
Output:
Removing Directory
To remove a directory, rmdir, unlink or delete methods are used. They perform same
function for a Ruby directory.
Syntax:
Dir.rmdir "dirName"
Example:
#!/usr/bin/ruby
Dir.rmdir "project"
puts Dir.exists? "project"
Output:
The existing method returns false as this directory is no longer present.
Ruby Exceptions
Ruby exception is an object, an instance of the class Exception or descendent of that
class. Itrepresents some exceptional condition.
We can declare some exception handlers within Ruby. An exception handler is a block
of codewhich is executed when exception occurs in some other block of code.
Exceptions are handled in two ways. Either you can terminate the program or deal with
the exception. To deal with an exception, you can provide a rescue clause. By providing
this, program control flows to the rescue clause.
When an exception is raised but not handled, global variable $! Contains the current
exception and $@ contains the current exception's back trace.
Ruby predefined classes like Exception and its children help you to handle errors of your
program. In Ruby exception hierarchy, most of the sub classes extend class Standard
Error. These are the normal exceptions.
NoMemoryError
ScriptError
SecurityError
SignalException
StandardError
SystenExit
SystemStackError
fatal - impossible to rescue
Example:
def raise_exception
puts 'I am before the raise.'
raise 'oops! An error has occurred'
puts 'I am after the raise'
end
raise_exception
Output:
Handling an Exception
To handle exception, the code that raises exception is enclosed within begin-end block.
Using rescue clauses we can state type of exceptions we want to handle.
Example:
def raise_and_rescue
begin
puts 'Before the raise.'
raise 'An error occurred.'
puts 'After the raise.'
rescue
puts 'Code rescued.'
end
puts 'After the begin block.'
end
raise_and_rescue
Output:
In the above example, interrupted code does not run completely. After exception
handling code resumes after the begin-end block.
If no argument is defined in the rescue clause, the parameter defaults to Standard Error.
Each rescue clause specify multiple exceptions to catch. If raise is used without any
parameters, exception may re-raised.
The rescue clauses are written in a begin/rescue block. Exceptions if not handled by one
rescue clause will be handled with the next one.
begin
code..
rescue OneTypeOfException
code..
rescue AnotherTypeOfException
code..
else
# Other exceptions
end
In the begin block, each rescue clause with the raised exception will be compared
against each of parameters in turn. It will be matched when the type of error thrown
and exception named in the rescue clause is either same or is a superclass of that
exception. The else clause is executed if body of begin statement is completed without
exceptions. If an exception occurs, else clause will not be executed.
Exception Object
Exception objects are normal objects. A rescued exception can be hold to a variable
within the rescue clause.
Example:
begin
raise 'an exception'
rescue ZeroDivisionError => e
puts "Exception Class: #{ e.class.name }"
puts "Exception Message: #{ e.message }"
puts "Exception Backtrace: #{ e.backtrace }"
end
The Exception class defines two methods that return details about the exception. The
message method returns a string that defines the explanation of error. The backtrace
method returns an array of string that represent the call stack at that point where
exception was raised
Syntax:
begin
code... rescue # capture exceptions
retry end # program will run from the begin block
Example:
#!/usr/bin/ruby
begin
x = Dir.mkdir "alreadyExist"
if x
puts "Directory created"
end
rescue
y = "newDir"
retry
end
Step 1 In the begin block, code is written to make a directory that already exists.
Syntax:
raise
Or,
raise "Error Message"
Or,
raise ExceptionType, "Error Message"
Or,
raise ExceptionType, "Error Message" condition
The first one re-raises the current exception. It is used for exception handlers where
exception isintercepted before passing it on.
The second one creates a new RuntimeError exception. This exception is then raised up
the call stack.
The third one uses first argument to create an exception then sets associated message
to the second argument.
The fourth one similar to third one, in this you can add any conditional statement to
raise an exception.
Example:
#!/usr/bin/ruby
begin
puts 'code before raise.'
raise 'exception occurred.'
puts 'code after raise.'
rescue
puts 'I am rescued.'
end
puts 'code after begin block.'
Output:
The ensure block will run at any case whether an exception arises, exception is rescued
or code is terminated by uncaught exception.
Syntax:
begin
code..
#..raise exception
Rescue
#.. exception is rescued
ensure
#.. This code will always execute.
end
Example:
begin
raise 'Exception'
rescue Exception => e
puts e.message
puts e.backtrace.inspect
ensure
puts "The ensure code will always run"
end
Output:
Syntax:
begin
code..
#..raise exception
rescue
# .. exception is rescued
else
#.. executes if there is no exception
ensure end #.. This code will always execute.
Example:
begin
# raise 'A test exception.'
puts "no exception is raised"
rescue Exception => e
puts e.message
puts e.backtrace.inspect
else
puts "else code will be executed as no exception is raised."
ensure
puts "ensure code will run"
end
Output:
The catch defines a block that is labeled with a given name. It is used to jump out of
nested code. Using catch, the block will be executed normally until throw is
encountered.
The catch and throw method is faster than rescue and raise clauses. Hence, it is more
suitable to use.
Syntax:
throw :lablename
#.. This code will not be executed
catch :lablename do
#.. Matching catch will be executed after a throw is encountered.
end
Or,
throw :lablename condition
#.. this code will not be executed
catch :lablename do
#.. matching catch will be executed after a throw is encountered.
end
Example:
def promptAndGet(prompt)
print prompt
res = readline.chomp
throw :quitRequested if res == "!"
return res
end
catch :quitRequested do
name = promptAndGet("Name: ")
age = promptAndGet("Occupation: ")
# ..
# process information
end
promptAndGet("Name:")
OOPs is a programming concept that uses objects and their interactions to design
applications and computer programs. Following are some basic concepts in OOPs:
Encapsulation
Polymorphism
Inheritance
Abstraction
Encapsulation: It hides the implementation details of a class from other objects due to
which a class is unavailable to the rest of the code. Its main purpose is to protect data
from data manipulation.
Inheritance: It creates new classes from pre-defined classes. New class inherits
behaviors of its parent class which is referred as superclass. In this way, pre-defined
classes can be made more reusable and useful.
Ruby Class
Ruby class defines blueprint of a data type. It defines what does that class name means.
A class is defined with a class keyword followed by the class name and is ended with
end keyword.
Conventionally, class name must begin with a capital letter. Class name with more than
one word run together with each word capitalized and no separating characters.
Creating Class
Example:
We will create a class Java with following command
class Greeter
A new class Java is created. The @name is an instance variable available to all the
methods of the Java class. It is used by say_welcome and say_bye.
Ruby Objects
In Ruby, everything is an object. When we create objects, they communicate together
through methods. Hence, an object is a combination of data and methods.
To create an object, first, we define a class. Single class can be used to create many
objects.Objects are declared using new keyword.
Creating Object
Example:
We have a class named Java. Now, let's create an object java and use it with following
command,
java = Java.new("John")
Once java object is created, it will use John as the name.
Ruby Methods
Methods are functions which are defined inside the body of a class. Data in Ruby is accessible only via
methods. There is a follow path in which Ruby looks when a method is called. To find out the method
lookup chain we can use ancestor’s method.
Defining Method
A method is defined with def keyword and ends with end keyword. We are defining a method name which
will display the following message.
The def keyword starts the definition of method name. Then we write body of the
method. Last line end indicates that method is defined.
Instance Methods
The instance methods are also defined with def keyword and they can be used using a
class instance only.
Example:
#!/usr/bin/ruby -w
# define a class
class Circle
# constructor method
def initialize(r)
@radius = r
end
# instance method
def getArea
3.14 * @radius * @radius
end
end
# create an object
circle = Circle.new(2)
# call instance methods
a = circle.getArea()
puts "Area of the box is : #{a}"
Output:
Ruby Inheritance
In inheritance, we create new classes using pre-defined classes. Newly created classes
are called derived classes and classes from which they are derived are called base
classes. With inheritance, a code can be reused again which reduces the complexity of a
program.
Ruby does not support multiple levels of inheritance. Instead it supports mixins.
In Ruby, < character is used to create a subclass. The syntax is shown below:
parentClass < subClass
Example:
#!/usr/bin/ruby
class Parent
def initialize
puts "Parent class created"
end
end
class Child < Parent
def initialize
super
puts "Child class created"
end
end
Parent.new
Child.new
In the above example, two classes are created. One is base Parent class and other is
derived Child class.
The super method calls the constructor of the Parent class. From the last two line, we
instantiate both the classes.
Output:
In the output, first the Parent class is created, derived Child class also calls the
constructor of its parent class and then Child class is created.
Ruby Constructor
A constructor is automatically called when an object is created. They do not return any
values. In Ruby, they are called initialize.
A constructor's main purpose is to initiate the state of an object. They can't be inherited.
The parent object constructor is called with super method.
Example:
#!/usr/bin/ruby
class Parent
def initialize
puts "Parent is created"
end
end
Parent.new
Output:
Ruby Regular Expression
A regular expression is also spelled as regexp which holds a regular expression, used to
match a pattern against strings. In Ruby, a pattern is written between forward slash
characters. They describe the content of a string. Ruby regular expression is more
similar to Perl regular expression.
Syntax:
/search string/
Ruby 1.9 uses Oniguruma regular expressions library but Ruby 2.0 uses Onigmo
regular expressions library. Onigmo is a fork library of Oniguruma adding some new
features.
=∽
This is the basic matching pattern. Here two operands are used. One is a regular
expression and other is a string. The regular expression is matched with the string.
If a match is found, the operator returns index of first match otherwise nil.
Example:
#match
This operator returns a MatchData object on matching otherwise nil.
Example:
Characters Classes
Meta characters have specific meaning in a pattern. To match a string, they are back
slashed (\\\)or escaped. A character class is encircled within square brackets.
[ab]
Here, [ab] means a or b. It is the opposite of /ab/ which means a and b.
Example:
[a-d]
Here, [a-d] is equivalent to [abcd]. The hyphen (-) character class represents range of
characters.
Example:
[^a-d]
The ^ sign represents any other character which is not present in the range.
Example:
Repetition
Characters defined till now match a single character. With the help of repetition meta
character, we can specify how many times they need to occur. These Meta characters
are called quantifiers.
Grouping
Grouping uses parentheses to group the terms together. Grouping the terms together
make them one.
Example:
(?:..)
This expression provides grouping without capturing. It combines term without creating
a back reference.
Example:
There are two levels of socket, high and low. Low level access allows you to work on
sockets that are supported by your system. It allows the implementation of both
connectionless and connection oriented protocols. High level access allows you to work
on network protocols like HTTP and FTP.
Example1
server1.rb
#!/usr/bin/ruby
require 'socket'
server = TCPServer.open(2017)
loop {
client = server.accept
client.puts "Hello. This is socket programming"
client.close
}
In the above code, the pre-installed socket module need to be included. We are using
2017 portion our system. You can use any port. Start a loop, accept all connections
made to port 2017 and send data to the client over socket networking. Lastly, close the
socket.
client1.rb
#!/usr/bin/ruby
require 'socket'
hostname = 'localhost'
port = 2017
s = TCPSocket.open(hostname, port)
while line = s.gets
puts line.chomp
end
s.close
In the above code, the pre-installed socket module need to be included. Create a socket
and connect it to port 2017. create a while loop to fetch all information sent over the
socket. Lastly, close the socket.
Output:
Go to the terminal, change to the directory to which you have saved the above two files.
We have saved it in our Desktop directory.
Now to execute these files, we need to have the required permission. Run the following
command in the terminal, chmod a+x *.rb
This command will make the entire Ruby files executable present in this directory.
Now open two terminals. In the first terminal execute server script and in the second
terminal execute client script with the following command.
ruby filename.rb
Example2
server3.rb
#!/usr/bin/env ruby -w
require "socket"
class Server
def initialize( port, ip )
@server = TCPServer.open( ip, port )
@connections = Hash.new
@rooms = Hash.new
@clients = Hash.new
@connections[:server] = @server
@connections[:rooms] = @rooms
@connections[:clients] = @clients
run
end
def run
loop {
Thread.start(@server.accept) do | client |
nick_name = client.gets.chomp.to_sym
@connections[:clients].each do |other_name, other_client|
if nick_name == other_name || client == other_client
client.puts "This username already exist"
Thread.kill self
end
end
puts "#{nick_name} #{client}"
@connections[:clients][nick_name] = client
client.puts "Connection established..."
listen_user_messages( nick_name, client )
end
}.join
end
def listen_user_messages( username, client )
loop {
msg = client.gets.chomp
@connections[:clients].each do |other_name, other_client|
unless other_name == username
other_client.puts "#{username.to_s}: #{msg}"
end
end
}
end
end
Server.new( 2019, "localhost" )
In the above code, server will have the same port as client side to establish connection.
Here we need one thread per connected user to handle all the possible users.
The run method verifies whether an entered name is unique or not. If username already
exists, connection will be killed otherwise connection will be established.
The listen_user_messages methods listen to the user messages and send them to all
the users.
client3.rb
#!/usr/bin/env ruby -w
require "socket"
class Client
def initialize( server )
@server = server
@request = nil
@response = nil
listen
send
@request.join
@response.join
end
def listen
@response = Thread.new do
loop {
msg = @server.gets.chomp
puts "#{msg}"
}
end
end
def send
puts "Enter your name:"
@request = Thread.new do
loop {
msg = $stdin.gets.chomp
@server.puts( msg )
}
end
end
end
server = TCPSocket.open( "localhost", 2019 )
Client.new( server )
Output:
Below snapshot shows chatting between two clients.
Ruby Multithreading
A normal program has single thread of execution. All the statements in the program are
executed sequentially.
A multi thread program has more than one thread of execution in it. It uses less
memory space and share same address space. Multithreading is used to perform more
than one task at once.
A new thread is created using thread.new call. It is different from the main thread's
execution.
Thread Initialization
To create a new thread Ruby provides three keywords namely, ::new, ::start and ::fork.
To start a new thread, associate a block of code with a call to Thread.new, Thread.start
orThread.fork. Thread will be created. The new thread exits when the block exit.
Syntax:
# Original thread runs
Thread.new {
# New thread is created.
}
# Original thread runs
Thread Termination
There are different ways to terminate a thread in Ruby. To exit a given thread, class ::kill
is used.
Syntax:
thr = Thread.new { ... }
Thread.kill(thr)
Output:
Thread Lifecycle
Once a thread is created, there is no need to start it. It automatically runs when it gets
proper CPU resources. The last expression in a block is the value of the thread. If thread
has run completely, value method returns the thread value, otherwise value method
blocks it and returns when the thread has completed. A number of methods are defined
by thread class while running query and manipulate the thread. By calling a thread's
Thread.join method, you can wait for a particular thread to finish.
To handle exception, you can use class method ::handle_interrupt. It will handle
exceptions asynchronously with threads.
Ruby thread class allows thread-local variables to be created and accessed by name.
Thread object is treated like a hash, writing elements using []= and reading them back
using [].
Thread Scheduling
Ruby supports scheduling threads by using ::stop and ::pass methods in a program.
The ::stop class method put the current running thread to sleep and schedule the
execution of another thread. Once the thread is asleep, instance method wakeup is used
to mark thread as eligible for scheduling.
The ::pass class method tries to pass execution to another thread. It depends upon the
operating system whether the running thread will switch or not.
Thread priority gives a hint to schedule threads according to their priority. The high
priority thread is scheduled first. It also depends upon the operating system. A thread
can increase or decrease its own priority as the first action it takes.
Thread Exclusion
Ruby thread exclusion states that, when two threads share the same data and one of the
thread modifies that data, then we need to ensure that no thread should see each
other’s data in an inconsistent state. For example, banking server . Where one thread
operates money transfer in accounts and other thread is generating monthly report for
the customers.
Ruby LDAP
Net::LDAP for Ruby is also written as net::ldap. It stands for Lightweight Directory Access
Protocol. It is an internet standard protocol used to access directory servers. Its basic
search unit is the entity, which corresponds to a person or other domain-specific object.
A directory which supports LDAP protocol, typically stores information about a number
of entities.
An example for attribute is sn. It stands for "surname". This attribute is generally used to
store a person's surname. Most of the directories follow standard convention that an
entity sn attribute will have exactly one value.
#add : The #add operation specifies a new DN and an initial set of attribute values. On
the success of operation, a new entity with the corresponding DN and attributes is
added to directory.
#delete : The #delete operation specifies an entity DN. On the success of operation,
the-entity and all its attributes is removed from directory.
#rename : The #rename operation is also called #modify_rdn. In earlier LDAP versions
the only way to change DN of an entity was to delete the whole entity and add it again
with a different DN. But with the introduction of #rename operation in version 3, you
can change the DN without discarding its attribute values.
Installing Net::LDAP
The net::LDAP is a pure Ruby library. It does not require any external library. Ruby Gems
version of Net::LDAP can be installed from usual sources.
Requirements
The Net::LDAP requires Ruby 2.0.0 interpreter or better.
If you have installed Gem version, then you need following library.
require 'rubygems'
require 'net/ldap'
Syntax:
LDAP::Conn.new(host='localhost', port=LDAP_PORT)
Now we can perform different operations like search, modify or delete inside block of
bind method with proper permissions.
Syntax:
Mod.new(mod_type, attr, vals)
mod_type :
You can add one or more option here like LDAP_MOD_ADD, LDAP_MOD_DELETE,
LDAP_MOD_REPLACE.
Example:
#/usr/bin/ruby -w
require 'rubygems'
require 'net/ldap'
$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn=root, dc=localhost, dc=localdomain','secret')
conn.perror("bind")
entry1 = [
LDAP.mod(LDAP::LDAP_MOD_REPLACE, 'sn', ['Steele']),
]
begin
conn.modify("cn=Anna williams, dc=localhost, dc=localdomain", entry1)
rescue LDAP::ResultError
conn.perror("modify")
exit
end
conn.perror("modify")
conn.unbind
The above example will modify the surname in the previous example.
Syntax:
conn.delete(dn)
#/usr/bin/ruby -w
require 'rubygems'
require 'net/ldap'
$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn=root, dc=localhost, dc=localdomain','secret')
conn.perror("bind")
begin
conn.delete("cn=Anna Steele, dc=localhost, dc=localdomain")
rescue LDAP::ResultError
conn.perror("delete")
exit
end
conn.perror("delete")
conn.unbind
Search in LDAP
There are three different modes to perform search with search method.
Example:
#/usr/bin/ruby -w
require 'rubygems'
require 'net/ldap'
$HOST = 'localhost'
$PORT = LDAP::LDAP_PORT
$SSLPORT = LDAP::LDAPS_PORT
base = 'dc=localhost,dc=localdomain'
scope = LDAP::LDAP_SCOPE_SUBTREE
filter = '(objectclass=java)'
attrs = ['sn', 'cn']
conn = LDAP::Conn.new($HOST, $PORT)
conn.bind('cn=root, dc=localhost, dc=localdomain','secret')
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
In this example, we will search the whole sub-tree of entry. In the last parameter of
search, you can specify any attributes. If nil is passed, all attributes a re-returned same
as "SELECT∗" in relational database.
It keeps track of small to medium amounts of data without any SQL based technique in
backend.
REXML is a pure Ruby XML processor. It represents a full XML document including PIs,
doc type, etc. An XML document has a single child that can be accessed by root(). If you
want to have an XML declaration for a created document, you must add one. REXML
documents do not write a default declaration for you.
REXML was inspired by Electric XML library for Java. Its API is easy to use, small size and
have followed the Ruby methodology for method naming and code flow. It supports
both tree and stream document parsing. Steam parsing is 1.5 times faster than tree
parsing. However, in stream parsing you don't get access to some features like XPath.
REXML features:
It is written 100 percent in Ruby.
It contains less than 2000 lines of code, hence, lighter in weight.
Its methods and classes are easy to understand.
It is shipped with Ruby installation. No need to install it separately.
It is used for both DOM and SAX parsing.
Example:
require 'rexml/document'
include REXML
file = File.new("trial.xml")
doc = Document.new(file)
puts docs
In the above code, the require statement loads the REXML library. Then include REXML
indicates that we don't have to use names like REXML::Document. We have created
trial.xml file. Document is shown on the screen.
Output:
The Document.new method takes IO, String object or Document as its argument. This
argument specifies the source from which XML document has to be read.
If a Document constructor takes a Document as argument, all its element nodes are
cloned to new Document object. If the constructor takes a String argument, string will
be expected to contain an XML document.
Example:
#!/usr/bin/env ruby
require 'rexml/document'
include REXML
info = <<XML
<info>
<name>Caroline</name>
<street>9820 St.</street>
<city>Seattle</city>
<contact>9854126575</contact>
<country>USA</country>
</info> XML
Document = Document.new( info )
puts document
Here, we use here Document info. All the characters including new lines between
<<EOF & EOF are part of info. For XML parsing examples, we will use following XML file
code as input:
file trial.xml
#!/usr/bin/ruby -w
require 'rexml/document'
include REXML
xmlfile = File.new("trial.xml")
xmldoc = Document.new(xmlfile)
# Now get the root element
root = xmldoc.root
puts "Root element : " + root.attributes["shelf"]
# This will output all the cloth titles.
xmldoc.elements.each("collection/clothing"){
|e| puts "cloth Title : " + e.attributes["title"]
}
# This will output all the cloth types.
xmldoc.elements.each("collection/clothing/type") {
|e| puts "cloth Type : " + e.text
}
# This will output all the cloth description.
xmldoc.elements.each("collection/clothing/description") {
|e| puts "cloth Description : " + e.text
}
Output:
Ruby XPath
Ruby XPath is a language to find information in an XML file. It is an alternative to view
XML file. It is used to navigate through elements and attributes in an XML document,
treating that document as a logical ordered tree.
Ruby XPath is very useful to get relevant information and attributes from XML file. It
takes tree-based parsing.
Example:
#!/usr/bin/ruby -w
require 'rexml/document'
include REXML
xmlfile = File.new("trial.xml")
xmldoc = Document.new(xmlfile)
Output:
Ruby XSLT
Ruby XSLT is a simple class based on libxml and libxslt. There are two XSLT parsers
available for Ruby.
Ruby-Sablotron
XSLT4R
Ruby-Sablotron
It is mainly written for Linux operating system and is written by Masayoshi Takahashi.
It requires the following libraries:
Sablot
Iconv
Expat
XSLT4R
It is written by Michael Neumann. It uses a simple command line interface and it can be
alternatively used within a third-party application to transform an XML document.
XSLT4R needs XMLScan to operate, which is included within the XSLT4R archieve. These
modules need to be installed using standard Ruby installation method.
Syntax:
ruby xslt.rb stylesheet.xsl document.xml [arguments]
To use XSLT4R within an application, you need to include XSLT and input the
parameters you need.