Documente Academic
Documente Profesional
Documente Cultură
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
memory-management(garbage
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:
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.
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
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)
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.
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.
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
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
Threads
Ruby
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
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.
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
#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
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.
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.
2 2 2 1 2 1
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
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