Sie sind auf Seite 1von 56

1

st

Day

RUBY

Introduction to Ruby
Ruby is a pure object-oriented programming

language . A dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write. Ruby was created by Yukihiro Matsumoto .

Ruby Features
interpreted Object-oriented portable untyped Automatic

collection) Easy and clear syntax

memory-management(garbage

Other Features of Ruby


Ruby is free, also for commercial applications. many existing libraries make programming easy . Ruby is permanently developed, without loosing backward-compatibility . There are interfaces to Python, Perl and Java. Thus existing programs can be reused. Many important data-structures are available (such as dynamic arrays (lists), strings, bignum, complex, ....) .

Ruby names:
ThefirstcharacterofanamehelpsRubytodistinguish its intendeduse instancevariablenamestartswitha@sign classvariablenamestartswitha@@sign globalvariablenamestartswitha$sign constantnamestartswithanuppercaseletter Methodnamesshouldbeginwithalowercaseletter ?and!aretheonlyweirdcharactersallowedasmethodnamesuff ixes !orbanglabelsamethodasdangerous-specifically useunderscorestoseparatewordsinamultiwordmethodor variable name Classnames,modulenamesandconstantsuse capitalization

Ruby Features:

#Rubyisdynamic x=7#integer x="house"#string x=7.5#real #InRuby,everythingyoumanipulateisanobject 'IloveRuby'.length


The basic types in Ruby are Numeric (subtypes include Fixnum, Integer, and Float), String, Array, Hash, Object, Symbol, Range, and RegEx. Ruby doesn't require you to use primitives (data types) when manipulating data of these types-if it looks like an integer, it's probably an integer; if it looks like a string, it's probably a string. class returns the class of an object, for example: s='hello' s.class#String In Ruby, everything you manipulate is an object, and the results of those manipulations are themselves objects. There are no primitives or data-types.

Strings

String literals are sequences of characters between single or double quotation marks. puts"HelloWorld" #Canuse"or'forStrings,but'ismoreefficient puts'HelloWorld' #Stringconcatenation puts'Ilike'+'Ruby' "hello".index('lo') #=> 3 "hEllO".upcase #=> "HELLO" #Newhere,displaysthestringthreetimes puts'Hello'*3 mystring = suresh,firoz,naresh,ramesh myarray = mystring.split(/,/) str =mystring.gsub(/firoz/,"Shyam") puts str In Ruby, strings are mutable. They can expand as needed, without using much time and memory. Ruby stores a string as a sequence of bytes.

1)if condition instruction1 instruction2 else instruction3 instruction4 end

Control Structures
2) if condition1 instruction1 ... instructionm elsif condition2 instructionm+1 ..... instructionk else instructionk+1 instructionl

3) Syntax for case statement: case variable when condition1 intruction1 when condition2 instruction2 ....... when conditionk instructionk else instructionk+1 end

end

3)Unless syntax is: unless condition instruction1 else instruction2 end

Loops
The While loop Code example: i=0 while i<10 puts i i += 1 end The Until loop Works similarly to the while loop. Example: i=0 until i == 10 puts "hello \n i += 1 end

The For loop A for loop will go through every item in a given set: for value in 1..10 puts "hello #{value.to_s} times" end

Regular Expressions

Regular expressions are put between two forward slashes (/) and escaped with a backward slash (\). Special characters (that need to be escaped to be matched) are: . | ( ) [ ] { } + \ ^ $ * ?. Ex: data = "Programming in Ruby" if data =~ /^P/ || data =~ /ming$/ data.gsub!(/[pr]/i, 'X') print "#{data}\n" end

Regular Expressions

In Ruby, a regular expression is written in the form of /pattern/modifiers where "pattern" is the regular expression itself, and "modifiers" are a series of characters indicating various options. The "modifiers" part is optional. This syntax is borrowed from Perl. Ruby supports the following modifiers: /i makes the regex match case insensitive. /m makes the dot match newlines. Ruby indeed uses /m, whereas Perl and many other programming languages use /s for "dot matches newlines". /x tells Ruby to ignore whitespace between regex tokens. /o causes any #{...} substitutions in a particular regex literal to be performed just once, the first time it is evaluated. Otherwise, the substitutions will be performed every time the literal generates a Regexp object. You can combine multiple modifiers by stringing them together as in /regex/is. In Ruby, the caret and dollar always match before and after newlines. Ruby does not have a modifier to change this. Use \A and \Z to match at the start or the end of the string. Since forward slashes delimit the regular expression, any forward slashes that appear in the regex need to be escaped. E.g. the regex 1/2 is written as /1\/2/ in Ruby.

Ruby Methods:
Amethodreturnsthevalueofthelastline Methodsthatactasqueriesareoftennamedwithatrailing? Methodsthatare"dangerous,"ormodifythereceiver,mightbenamed withatrailing!(Bangmethods)

#Asimplemethod defhello puts'Hello' end #usethemethod hello #Methodwithanargument-1 defhello1(name) puts'Hello'+name return'success' end puts(hello1('satish'))

Sample program
def fact(n) if n == 0 1 else n * fact(n-1) end end puts "Enter number" c=gets n=c.to_i puts "Factorial of #{n} is #{fact(n)}"

Exception Handling
begin x=3/0 puts x rescue ArgumentError puts "wrong no of arguments" rescue ZeroDivisionError puts "division by zero is illegal rescue puts "There is some unknown exception" end

Exception Handling
def Division(x,y) if(y==0) raiseexception end z=x/y puts z end def raiseexception begin puts 'There is an error:' raise rescue puts 'Division by Zero is Illegal' end exit(1) end Division(4,0)

Output: There is an error: Division by Zero is Illegal

ARRAYS

The class Array holds a collection of object references. Each object reference occupies a position in the array, identified by a non-negative integer index. You can create arrays using literals or by explicitly creating an Array object. A literal array is simply a list of objects between square brackets.

Example for Arrays


EX1: a=[3.14159,"pie",99] a.type Array a.length 3 a[0] 3.14159 a[1] "pie" a[2] 99 a[3] nil EX2: b=Array.new b[0]=1 b[1]=4 puts b [1,4] b.sort (or) b.reverse puts b

Array usage
Stack Example:
b=Array.new b[0]=1 b[1]=2 b.push 3 b.push 4 b.push 5 b.push 6 puts "Satck elements are: " puts b b.pop b.pop puts "after pop Stack elements:" puts b

Queue Example:
b=Array.new b[0]=1 b[1]=2 b << 3 b << 4 b << 5 b << 6 puts Queue elements are: " puts b b.shift b.shift puts "after shift Queue Elements: " puts b

Hashes

Hashes (sometimes known as associative arrays or dictionaries) are similar to arrays, in that they are indexed collectives of object references. However, while you index arrays with integers, you can index a hash with objects of any type: strings, regular expressions, and so on. When you store a value in a hash, you actually supply two objects---the key and the value. You can subsequently retrieve the value by indexing the hash with the same key. The values in a hash can be any objects of any type. The example that follows uses hash literals: a list of key=>value pairs between braces. Compared with arrays, hashes have one significant advantage: they can use any object as an index. However, they also have a significant disadvantage: their elements are not ordered, so you cannot easily use a hash as a stack or a queue.

Example for Hash


EX1: h={'dog'=>'canine','cat'=>'feline','donkey' =>'asinine'} Puts h.length 3 Puts h['dog'] "canine" Puts h['cow']='bovine' h[12]='dodecine' h['cat']=99 h.delete(dog) Puts h {"cow"=>"bovine","cat"=>99,12=>"dodecine, "donkey"=>"asinine"}

EX2: people = Hash.new people[:nickname] = 'IndianGuru' people[:language] = 'Marathi' people[:lastname] = 'Tamil' puts people[:lastname] # Tamil

Operations on Hash
names = {"Jack" => "Ruby", "Monty" => "python", "Blaise"=>"Pascal", "Minnie"=>"Perl"} list=names.sort puts list puts " \nOne elenent in list:\n " puts list[3][1]

Operaions on Hash
Creating a Hash from an Array array = [2,3,4,5,6,7,8,9] hash=Hash[*array] #hash is now: {2=>3, 4=>5, 6=>7, 8=>9} Merging two Hashes h1={base=>foundation, pedestal=>base} h2={base=>non-acid, salt=>NaCl} H3 = h1.merge(h2) { |key,old,new| old < new ? old : new } Output: H3 => {salt=>NaCl, pedestal=>base, base=>foundation}

Iterators

An iterator is a special kind of method. It is a method that lets you access items one at a time. Arrays are not the only objects that have iterators, but the are one of the most important. Iterators are best seen through an example. Here we use Array#each

Example for Iterator


friends = ["Melissa", "Jeff", "Ashley", Rob] friends.each do |friend| puts "I have a friend called " + friend end Output: I have a friend called Melissa I have a friend called Jeff I have a friend called Ashley I have a friend called Rob

Iterator for Hash


names = {"W" => 666 , "X" => 777, "Y"=>888, "Z"=>999} names.each do |key,val| print key, " value is ", val, ";\n" end Output: W value is 666; X value is 777; Y value is 888; Z value is 999;

Ranges
digits=0..9 sclae=09 The operator .. is inclusive its endpoint. And the operator is exclusive of its end point. r1= 3..6 #closed r2=36 #open a1=r1.to_a #{3,4,5,6} a2=r2.to_a #{3,4,5}

Operations on Ranges
Iterating

over ranges (3..6).each {|x| puts x } Membership testing r1=23456..34567 x=141142 y=31416 r1.include?(x) #false r1.include?(y) #true

Working with Files


# Create a new file and write to it File.open('testfile.rb', 'w') do |f2| # use "\n" for two lines of text f2.puts "Created by Suresh\nThank God!" end File.open('getfile.rb', 'w') do |f2| File.open('testfile.rb', 'r') do |f1| while line = f1.gets puts line f2.write(line) end end end

Threads
Ruby

threads are user-level threads and are operating system independent.

Ex: thread = Thread.new do puts hi end

Accessing thread variables


a=3 b=4 c=5 puts a thread = Thread.new(a,b,c) do |a,x,y| a=4 x=89 y=88 thread[:f] = 34 end puts a puts "" puts thread[:f]

Thread - status
t1 = Thread.new { loop { } } t2 = Thread.new { sleep 5 } t3 = Thread.new { Thread.stop } t4 = Thread.new { raise exceptionsss } t5 = Thread.new { Thread.exit } puts "Thread t1 status: #{t1.status}" puts "Thread t2 status: #{t2.status}" puts "Thread t3 status: #{t3.status}" puts "Thread t4 status: #{t4.status}" puts "Thread t5 status: #{t5.status}"

Synchronizing Threads
x=0 t1= Thread.new do 1.upto(1000) do Thread.critical = true x = x+1 Thread.critical = false end end t2= Thread.new do 1.upto(1000) do Thread.critical = true x = x+1 Thread.critical = false end end t1.join t2.join puts x

Synchronizing Threads
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!" } } puts "(Later, back at the ranch...)" b = Thread.new { mutex.synchronize { puts "B: Now I am critical, but am done with cv" cv.signal puts "B: I am still critical, finishing up" } } a.join b.join

2nd Day

OOPS & DYNAMIC FEATURES

Classes and Objcts


class First def initialize() @x =786 end def wish puts "Hello world" puts @x end end s = First.new s.wish

Ruby Access Control

The only easy way to change an object's state in Ruby is by calling one of its methods. Control access to the methods, and you have controlled access to the object. A good rule of the thumb is never to expose methods that could leave an object in an invalid state. Ruby gives you three levels of protection: Public methods can be called by everyone - no access control is enforced. A class's instance methods (these do not belong only to one object; instead, every instance of the class can call them) are public by default; anyone can call them. The initialize method is always private. Protected methods can be invoked only by objects of the defining class and its subclasses. Access is kept within the family. Private methods cannot be called with an explicit receiver - the receiver is always self. This means that private methods can be called only in the context of the current object; you cannot invoke another object's private methods. Access control is determined dynamically, as the program runs, not statically. You will get an access violation only when the code attempts to execute the restricted method.

Access Control Example:


classClassAccess defm1#thismethodispublic end protected defm2#thismethodisprotected end private defm3#thismethodisprivate end end ca=ClassAccess.new ca.m1 ca.m2 ca.m3 Alternatively, you can set access levels of named methods by listing them as arguments to the access control functions. classClassAccess defm1#thismethodispublic end public:m1 protected:m2,:m3 private:m4,:m5 end

An example for 'protected' access control:


classPerson definitialize(age) @age=age end defage @age end defcompare_age(c) ifc.age>age "Theotherobject'sageisbigger." else "Theotherobject'sageisthesameorsmaller." end end protected:age end chris=Person.new(25) marcos=Person.new(34) putschris.compare_age(marcos) The output is: Theotherobject'sageisbigger.

Accessor methods
Encapsulation is achieved when the instance

variables are private to an object and you have public getters and setters (in Ruby, we call them attribute readers and attribute writers).
To make instance variables available, Ruby

provides accessor methods that return their values.

Example for Accessor Attributes


#Firstwithoutaccessormethods
classSong definitialize(name,artist) @name=name @artist=artist end defname @name end defartist @artist end end song=Song.new("Brazil","Ivete") putssong.name putssong.artist

#Now,withaccessormethods
classSong definitialize(name,artist) @name=name @artist=artist end attr_reader:name,:artist #Forcreatingreaderandwritermethods #attr_accessor:name #Forcreatingwritermethods #attr_writer:name end song=Song.new("Brazil","IveteSangalo") putssong.name putssong.artist

Inheritance

Inheritance is a relation between two classes. We know that all cats are mammals, and all mammals are animals. The benefit of inheritance is that classes lower down the hierarchy get the features of those higher up, but can also add specific features of their own. If all mammals breathe, then all cats breathe. In Ruby, a class can only inherit from a single other class. Some other languages support multiple inheritance, a feature that allows classes to inherit features from multiple classes, but Ruby doesn't support this.

Inheritance Example
classMammal defbreathe puts"inhaleandexhale" end end classCat<Mammal defspeak puts"Meow" end end rani=Cat.new rani.breathe rani.speak

Example for inheritance


classBird defpreen puts"Iamcleaningmyfeathers." end deffly puts"Iamflying." end end classPenguin<Bird deffly puts"Sorry.I'dratherswim." end end p=Penguin.new p.preen p.fly

Multiple Inheritance
module SmallModule def hello puts "Hello....small" end def add puts "Called add method of SmallModule" end end class MultipleInher include BigModule include SmallModule def hello super puts "Hello..Suresh" end end s = MultipleInher.new s.hello s.add s.del

module BigModule def del puts "Called del method of BigModule" end def hello puts "Hello...big" end end

Output: Hello....small Hello..Suresh Called add method of SmallModule Called del method of BigModule

Method overloading

You want to create two different versions of a method with the same name: two methods that differ in the arguments they take. However, a Ruby class can have only one method with a given name. Within that single method, though, you can put logic that branches depending on how many and what kinds of objects were passed in as arguments.

Example for Method overloading


class Rectangle def initialize(*args) if args.size < 2 || args.size > 3 raiseexception else if args.size == 2 @@x = 2 puts 'Two arguments' else @@x =3 puts 'Three arguments' end end end def Area puts @@x end def raiseexception begin puts 'There is an error:' raise rescue puts 'Agguments must be either 2 or 3' end end

Continued..
a = Rectangle.new([10, 23], 4, 10) b= Rectangle.new([10, 23], [14, 13]) a.Area c= Rectangle.new(14) Output: >ruby class.rb Three arguments Two arguments 2 There is an error: Arguments must be either 2 or 3 >Exit code: 0

Method Overriding
In object oriented programming, is a language feature that allows a subclass to provide a specific implementation of a method that is already provided by one of its superclasses. The implementation in the subclass overrides (replaces) the implementation in the superclass. Here's an example: classA defa puts'InclassA' end end classB<A defa puts'InclassB' end end b=B.new b.a

Usage of super
The way super handles arguments is as follows:

When you invoke super with no arguments Ruby sends a message to the parent of the current object, asking it to invoke a method of the same name as the method invoking super. It automatically forwards the arguments that were passed to the method from which it's called. Called with an empty argument list - super()-it sends no arguments to the higher-up method, even if arguments were passed to the current method. Called with specific arguments - super(a, b, c) - it sends exactly those arguments.

Example for super usage


classBicycle attr_reader:gears,:wheels,:seats definitialize(gears=1) @wheels=2 @seats=1 @gears=gears end end classTandem<Bicycle definitialize(gears) super @seats=2 end end t=Tandem.new(2) The output is: putst.gears putst.wheels putst.seats b=Bicycle.new putsb.gears putsb.wheels putsb.seats

2 2 2 1 2 1

Dynamic Features of Ruby


Dynamic

typing Coding at run time Reflection Missing methods Garbage collection

Coding at runtime
def calculate(op1,operator,op2) str = op1.to_s + operator + op2.to_s eval(str) end puts calculate(2,"*",3) puts calculate(2,+",3) puts calculate(2,-",3) Output: 6 5 -1

Ruby Dynamic Methods

Has a feature call method missing, which allows your class to react to unknown method calls without raising a unknown-method error. This allows a class to answer to whatever method is called. Which is very useful if you are writing a Ruby binding to a component you query also dynamically, because with this way method_missing act as a gateway only, forwarding the message (method name) and the parameters, after doing the appropiate conversion.

Method_missing Example
class Dynamic def hello(str) puts "Hello " + str end def method_missing(*args) str = args[0].to_s puts str + " method is unavailable." end end r= Dynamic.new r.hello('suresh') r.add

Output: Hello suresh Add method is unavailable.