Welcome to GKTCS Innovations Pvt. Ltd.

IT Training .Consultancy . Software Innovations. Staffing

Surendra Panpaliya

Director, GKTCS Innovations Pvt. Ltd, Pune.

18 + Years of Experience ( MCA, PGDCS, BSc. [Electronics] , CCNA) Director , GKTCS Innovations Pvt. Ltd. Pune [ Nov 2009 – Till date ] IT Manager and Consultant at Rolta India Ltd, Mumbai [ April 2007 – Oct 2009 ] Associate Professor at Sinhgad Institute , Pune [Jan 2002 – April 2007] Instructor , ITM Bangalore [ May 2000 – Jan 2002 ] Project Trainee, DSYS Software Group, Bangalore [ Jan 1999 to April 2000] Skills ❑ Ruby, Rail,Python, Jython, Django, Android , PHP, LAMP ❑ Data Communication & Networking, CCNA ❑ UNIX /Linux Shell Scripting, System Programming ❑ CA Siteminder, Autosys, SSO, Service Desk, Service Delivery Author of 4 Books National Paper Presentation Awards at BARC Mumbai 2 Agenda ( Day 1)

◆ Introduction to Ruby ◆ What's New in Ruby? ◆ Basic Concept ◆ Array and Hashes ◆ Control Structures ◆ Regular Expressions ◆ Blocks and Iterators ◆ Reading and Riting Agenda ( Day 2 )

◆ Classes, Objects, And Variables ◆ Containers, Blocks, and Iterators ◆ Standard Types ◆ Methods ◆ Expressions Agenda

◆ Exceptions, Catch, and Throw ◆ Modules ◆ Basic Input and Output ◆ Threads and Processes ◆ Unit Testing ◆ Ruby Debugger ◆ Package Management With Ruby Rails Agenda

◆ Basic Input and Output ◆ Threads and Processes ◆ Unit Testing ◆ Ruby Debugger ◆ Package Management With Ruby Rails Introduction

What is Ruby ?

Why Ruby? Introduction

Ruby is "an interpreted for quick and easy object-oriented programming" -- what does this mean? interpreted scripting language:

● ability to make operating system calls directly ● powerful string operations and regular expressions ● immediate feedback during development Introduction quick and easy:

● variable declarations are unnecessary ● variables are not typed ● syntax is simple and consistent ● memory management is automatic Introduction object oriented programming:

● everything is an object ● classes, methods, inheritance, etc. ● singleton methods ● "mixin" functionality by module ● iterators and closures Introduction

● multiple precision integers ● convenient exception processing ● dynamic loading ● threading support

● If you are unfamiliar with some of the concepts above, don't worry?

● The mantra of the ruby language is quick and easy. Introduction

Matz : Computer Scientist

● Yukihiro Matsumoto is a Japanese computer scientist and software programmer best known as the chief designer of the Ruby and its reference implementation, Matz's Ruby Interpreter. Born: April 14, 1965, Osaka, Osaka Prefecture, Japan Known for: Ruby Education: Introduction

Matz : Yukihiro Matsumoto

● Ruby is a dynamic, reflective, object-oriented, general- purpose programming language.

● It was designed and developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan.

● According to its authors, Ruby was influenced by Perl, Smalltalk, Eiffel, Ada, and Lisp.[13] It supports multiple programming paradigms, including functional, object-oriented, and imperative.

● It also has a dynamic type system and automatic memory management. Introduction

Matz : Yukihiro Matsumoto

● Matsumoto describes the design of Ruby as being like a simple Lisp language at its core, with an object system like that of Smalltalk, blocks inspired by higher-order functions, and practical utility like that of Perl.

● The name "Ruby"

● The name "Ruby" originated during an online chat session between Matsumoto and Keiju Ishitsuka on February 24, 1993, before any code had been written for the language.

● Initially two names were proposed: "Coral" and "Ruby".

● Matsumoto chose the latter in a later e-mail to Ishitsuka.

● Matsumoto later noted a factor in choosing the name "Ruby" – it was the birthstone of one of his colleagues. Introduction

Matz : Yukihiro Matsumoto

● First publication

● The first public release of Ruby 0.95 was announced on Japanese domestic newsgroups on December 21, 1995.

● Subsequently three more versions of Ruby were released in two days.

● The release coincided with the launch of the Japanese- language ruby-list mailing list, which was the first mailing list for the new language.

● Already present at this stage of development were many of the features familiar in later releases of Ruby, including object- oriented design, classes with inheritance, mixins, iterators, closures, exception handling and garbage collection. Introduction

Matz : Yukihiro Matsumoto

● Early releases

● Following the release of Ruby 0.95 in 1995, several stable versions of

● Ruby were released in the following years:

● Ruby 1.0: December 25, 1996[16]

● Ruby 1.2: December 1998

● Ruby 1.4: August 1999

● Ruby 1.6: September 2000

● In 1997, the first article about Ruby was published on the Web. In the same year, Matsumoto was hired by netlab.jp to work on Ruby as a full-time developer. Introduction

Matz : Yukihiro Matsumoto

● Early releases

● In 1998, the Ruby Application Archive was launched by Matsumoto, along with a simple English-language homepage for Ruby.

● In 1999, the first English language mailing list ruby-talk began, which signaled a growing interest in the language outside Japan.

● By 2000, Ruby was more popular than Python in Japan.

● In September 2000, the first English language book Programming Ruby was printed, which was later freely released to the public, further widening the adoption of Ruby amongst English speakers.

● In early 2002, the English-language ruby-talk mailing list was receiving more messages than the Japanese-language ruby-list, demonstrating Ruby's increasing popularity in the English-speaking world. Introduction

Matz : Yukihiro Matsumoto

● Early releases

● Ruby 2.1

● Ruby 2.1.0 was released on Christmas Day in 2013.[35] The release includes speed-ups, bugfixes, and library updates. Starting with 2.1.0, Ruby is using semantic versioning.[36]

● Ruby 2.2

● Ruby 2.2.0 was released on Christmas Day in 2014.

● The release includes speed-ups, bugfixes, and library updates and removes some deprecated APIs. Most notably, Ruby 2.2.0 introduces changes to memory handling - an incremental garbage collector, support for garbage collection of symbols and the option to compile directly against jemalloc. It also contains experimental support for using vfork(2) with system() and spawn(), and added support for the Unicode 7.0 specification. Introduction

Matz : Yukihiro Matsumoto

● Early releases

● Ruby 1.8 was initially released in August 2003, was stable for a long time, and was retired June 2013.[25] Although deprecated, there is still code based on it. Ruby 1.8 is only partially compatible with Ruby 1.9.

● Around 2005, interest in the Ruby language surged in tandem with , a web application framework written in Ruby. Rails is frequently credited with increasing awareness of Ruby.

● Ruby 1.9 was released in December 2007. Effective with Ruby 1.9.3, released October 31, 2011,

● Ruby switched from being dual-licensed under the and the GPL to being dual-licensed under the Ruby License and the two- clause BSD license. Adoption of 1.9 was slowed by changes from 1.8 that required many popular third party gems to be rewritten. Introduction

Matz : Yukihiro Matsumoto

● Early releases

● Ruby 2.0 added several new features, including:

● method keyword arguments,

● a new method, Module#prepend, for extending a class,

● a new literal for creating an array of symbols,

● new API for the lazy evaluation of Enumerables, and

● a new convention of using #to_h to convert objects to Hashes.[33]

● Ruby 2.0 is intended to be fully backward compatible with Ruby 1.9.3. As of the official 2.0.0 release on February 24, 2013, there were only five known (minor) incompatibilities.

● To know about rails releases:

● http://railsapps.github.io/rails-release-history.html Philosophy

Matz : Yukihiro Matsumoto

● Matsumoto has said that Ruby is designed for programmer productivity and fun, following the principles of good user interface design.

● At a Google Tech Talk in 2008 Matsumoto further stated, "I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language."

● He stresses that systems design needs to emphasize human, rather than computer, needs. Philosophy

Matz : Yukihiro Matsumoto

● Often people, especially computer engineers, focus on the machines. They think,

● "By doing this, the machine will run fast. By doing this, the machine will run more effectively. By doing this, the machine will something something something."

● They are focusing on machines. But in fact we need to focus on humans, on how humans care about doing programming or operating the application of the machines.

● We are the masters. They are the slaves. Introduction

Matz : Yukihiro Matsumoto

● Ruby was conceived on February 24, 1993.

● In a 1999 post to the ruby-talk mailing list,

● Ruby author Yukihiro Matsumoto describes some of his early ideas about the language:

● I was talking with my colleague about the possibility of an object- oriented scripting language. I knew Perl (Perl4, not Perl5), but I didn't like it really, because it had the smell of a toy language (it still has). The object-oriented language seemed very promising. I knew Python then. But I didn't like it, because I didn't think it was a true object-oriented language — OO features appeared to be add-on to the language. As a language maniac and OO fan for 15 years, I really wanted a genuine object-oriented, easy-to-use scripting language. I looked for but couldn't find one. So I decided to make it. Features

• Simple Syntax • Normal Object-oriented Features (e.g. class, method calls) • Advanced Object-oriented Features (e.g. mix-in, singleton- method) • Operator Overloading • Exception Handling • Iterators and Closures • Garbage Collection • Dynamic Loading of Object Files (on some architectures) • Highly Portable (works on many Unix-like/POSIX compatible platforms as well as Windows, macOS, Haiku, etc.) cf. bugs.ruby-lang.org/projects/ruby-trunk/wiki/ SupportedPlatforms Semantics

● Ruby is object-oriented: every value is an object, including classes and instances of types that many other languages designate as primitives (such as integers, booleans, and "null").

● Variables always hold references to objects.

● Every function is a method and methods are always called on an object.

● Methods defined at the top level scope become members of the Object class.

● Since this class is an ancestor of every other class, such methods can be called on any object.

● They are also visible in all scopes, effectively serving as "global" procedures. Semantics

● Ruby supports inheritance with dynamic dispatch, mixins and singleton methods (belonging to, and defined for, a single instance rather than being defined on the class).

● Though Ruby does not support multiple inheritance, classes can import modules as mixins.

● Ruby has been described as a multi-paradigm programming language:

● Allows procedural programming (defining functions/variables outside classes makes them part of the root, 'self' Object),

● Object orientation (everything is an object) or

● Functional programming (it has anonymous functions, closures, and continuations; statements all have values, and functions return the last evaluation). How to get Ruby?

For a complete list of ways to install Ruby, including using third-party tools like rvm, see: www.ruby-lang.org/en/downloads/

The Ruby distribution files can be found on the following FTP site: ftp.ruby-lang.org/pub/ruby/

The trunk of the Ruby source tree can be checked out with the following command:

$ svn co https://svn.ruby-lang.org/repos/ruby/trunk/ ruby Or if you are using git then use the following command:

$ git clone https://github.com/ruby/ruby.git There are some other branches under development. Try the following command to see the list of branches: $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/ Or if you are using git then use the following command:

$ git ls-remote git://github.com/ruby/ruby.git How to get Ruby?

Ruby home page The URL of the Ruby home page is: www.ruby-lang.org/

Mailing list There is a mailing list to talk about Ruby. To subscribe to this list, please send the following phrase: subscribe in the mail body (not subject) to the address [email protected].

Ruby References https://launchschool.com/books/ruby/read/basics#strings https://launchschool.com/books/ruby/read/arrays#whatisanarray Getting Started

◆ Surendras-MacBook-Pro:~ SurendraMac$ rails -v ◆ Rails 5.2.1 ◆ Surendras-MacBook-Pro:~ SurendraMac$ irb ◆ 2.5.1 :001 > puts("Welcome to Ruby") ◆ Welcome to Ruby ◆ => nil ◆ 2.5.1 :002 > puts "Welcome" ◆ Welcome ◆ => nil ◆ SurendraMac$ ruby -e 'puts "Welcome to ruby" ' Ruby Help

ri and RDoc If you have a good internet connection, then you would probably refer to the Ruby documentation online. However, for those with a slower connection or not having an internet access, the Ruby ri and RDoc tools are very useful. http://ruby-doc.org/core-2.5.1/ ri (Ruby Index) and RDoc (Ruby Documentation) are a closely related pair of tools for providing documentation about Ruby programs. ri is a command-line tool; the RDoc system includes the command-line tool . ri and rdoc are standalone programs; you run them from the command line.

◆ $ ri Array.sort

◆ $ ri Array

◆ $ ri Hash#each

◆ $ ri Math::sqrt Getting Started

◆ Surendras-MacBook-Pro:RubyEx SurendraMac$ gem install

◆ Fetching: coderay-1.1.2.gem (100%)

◆ Successfully installed coderay-1.1.2 ◆ Fetching: pry-0.11.3.gem (100%)

◆ Successfully installed pry-0.11.3

◆ invalid options: -SNw2

◆ (invalid options are ignored)

◆ Parsing documentation for coderay-1.1.2 ◆ Installing ri documentation for coderay-1.1.2

◆ Parsing documentation for pry-0.11.3

◆ Installing ri documentation for pry-0.11.3

◆ Done installing documentation for coderay, pry after 3 seconds

◆ 2 gems installed

◆ Surendras-MacBook-Pro:RubyEx SurendraMac$ Getting Started

◆ SurendraMac$ pry ◆ [1] pry(main)> puts "Hi" ◆ Hi

◆ => nil

◆ [2] pry(main)> print"Hello" ◆ Hello=> nil ◆ [3] pry(main)> 434 + 434

◆ => 868 Getting Started

$ echo "puts 'hello world'" > hello.rb $ ruby hello.rb hello world Getting Started

◆ [7] pry(main)> def sum(x,y) ◆ [7] pry(main)* x+y ◆ [7] pry(main)* end ◆ => :sum ◆ [8] pry(main)> sum(5,6) ◆ => 11 ◆ [9] pry(main)> Getting Started

◆ irb—Interactive Ruby—is the tool of choice for executing Ruby inter- actively. ◆ irb is a Ruby Shell, complete with command- line history, line-editing capabilities, and job control. ◆ % irb irb(main):001:0> def sum(n1, n2) irb(main):002:1> n1 + n2 irb(main):003:1> end Getting Started irb(main):004:0> sum(3, 4) => 7 irb(main):005:0> sum("cat", "dog") => "catdog" Getting Started

◆ irb(main):001:0> load "ruby_ex/fib_example.rb" => true irb(main):002:0> Fibonacci.upto(20) => [1, 1, 2, 3, 5, 8, 13] Simple example

$ ./myprog.rb Ruby Programs Shebang ! #!/usr/local/bin/ruby -w puts "Hello, world!" Simple example

$ ./myprog.rb Hello, world! Ruby Documentation: RDoc and ri http://www.ruby-doc.org ri ClassName ri -c. % ri GC ------Class: GC The GC module provides an interface to Ruby's mark and sweep garbage collection mechanism. Some of the underlying methods are also available via the ObjectSpace module. Simple example

# Program to find the factorial of a number # Save this as fact.rb def fact(n) if n == 0 1 else n * fact(n-1) end end puts fact(ARGV[0].to_i) Simple example

Here, ARGV is an array which contains the command line arguments, and to_i converts a character string to an integer.

$ ruby fact.rb 1 1 $ ruby fact.rb 5 120 Simple example

The input/evaluation loop When you invoke ruby with no arguments, it reads commands from standard input and executes them after the end of input: $ruby puts "hello world" puts "good-bye world" ^D hello world good-bye world

● The ^D above means control-D, a conventional way to signal end- of-input in a Unix context. In DOS/Windows, try pressing F6 or ^Z instead. Variables

● A variable is an identifier or name that can be assigned a value, and a value has, or will have,a type at runtime(when the program runs). Local Variables x = 100 Instance Variables @hello = hello Class Variables @@times = 0 Global Variables $amount = "0.00" Constants

● A constant holds a constant value for the life of a Ruby program. Constants are variables whose names are capitalized or all uppercase. Here is the definition of a con- stant named Matz: ● Matz = "Yukihiro Matsumoto" ● puts Matz # => Yukihiro Matsumoto ● If a constant is defined within a class or module, you can access the constant from within that class or module; if it is defined outside either a class or module, the con- stant is available globally. Unlike other languages, a Ruby constant is mutable—that is, you can change its value. Parallel Assignment

● With parallel assignment, you do the same thing by separating the variables, then the values, with commas:

● x, y, z = 100, 200, 500 ● You can even assign values of different kinds, such as a string, float, and integer:

● a, b, c = "cash", 1.99, 100 ● Parallel assignment is convenient. It’s just got Ruby written all over it. Operators

Operator Description Method :: Scope resolution [] []= Reference, set ✓ ** Raise to power (exponentiation) ✓ + - ! ~ Positive (unary), negative (unary), logical negation, complement✓ (not !) * / % Multiplication, division, modulo (remainder) ✓ + - Addition, subtraction ✓ Comments

# I am a comment. Just ignore me. =begin This is a comment. This is a comment, too. This is a comment, too. I said that already. =end A block can comment out one line or as many lines as you want. Strings

A string is a sequence of letters, numbers, and other characters. ruby> "abc" "abc" ruby> 'abc' "abc" A double-quoted string allows character escapes by a leading backslash, and the evaluation of embedded expressions using #{}. A single-quoted string does not do this interpreting; what you see is what you get. Number

Ruby provides a number of built-in number classes. In this section we will explore some of the more commonly used classes. Integer Class The base class from which the following number classes are derived. Float Class The Float object represents real numbers based on the native architecture‘s double-precision floating point representation. 45] pry(main)> Float => Float [46] pry(main)> Float.class => Class Number

36] pry(main)> Fixnum (pry):38: warning: constant ::Fixnum is deprecated => Integer [38] pry(main)> Integer => Integer [39] pry(main)> Integer.class => Class [40] pry(main)> Integer.methods => [:sqrt, :allocate, [42] pry(main)> String => String [43] pry(main)> String.methods Number

●Rational Class ●Rational implements a rational class for numbers. ●A rational number is a number that can be expressed as a fraction p/q where p and q are integers and q is not equal to zero.

●A rational number p/q is said to have numerator p and denominator q. ●Numbers that are not rational are called irrational numbers. ●[49] pry(main)> Rational.class ●=> Class ●[50] pry(main)> x=Rational(5/2)

●=> (2/1) ●[51] pry(main)> Number

● Numbers can be converted from one type to another using the Ruby Integer and Float methods. These methods take as an argument the value to be converted. For example: ● Convert Floating Point Number to an Integer ● Integer (10.898) ● => 10 ● Convert a String to an Integer ● Integer ("10898") ● => 10898 Number

● Convert a Hexadecimal Number to an Integer ● Integer (0xA4F5D) ● => 675677 ● Convert an Octal Number to an Integer ● [55] pry(main)> Integer (01231) ● => 665 ● Convert a Binary Number to an Integer ● [54] pry(main)> Integer (0b01110101) ● => 117 Number

● Convert an Integer Floating Point ● Float (10) ● => 10.0 ● Convert a String to Floating Point ● Float ("10.09889") ● => 10.09889 ● Convert a Hexadecimal Number to Floating Point ● Float (0xA4F5D) ● => 675677.0 Number

● Convert an Octal Number to a Floating Point ● Float (01231) ● => 665.0 ● Convert a Binary Number to Floating Point ● Float (0b01110101) ● => 117 Strings ruby> puts "a\nb\nc" a b c nil ruby> puts 'a\nb\n' a\nb\nc nil Strings ruby> "\n" "\n" ruby> '\n' "\\n" ruby> "\001" "\001" ruby> '\001' "\\001" Strings

[56] pry(main)> "abcd #{5*3} efg" => "abcd 15 efg" ruby> var = " abc " " abc " ruby> "1234#{var}5678" "1234 abc 5678" Strings

● Ruby's string handling is smarter and more intuitive than C's. ● For instance, you can concatenate strings with +, and repeat a string many times with *: ruby> "foo" + "bar" "foobar" ruby> "foo" * 2 "foofoo" Strings

● Concatenation: ● ruby> word = "fo" + "o" ● "foo"

● Repetition:

● ruby> word = word * 2 ● "foofoo" Strings

● Extracting characters (note that characters are integers in ruby): irb(main):009:0> word[0] => "f" irb(main):010:0> word[-1] => "o" irb(main):011:0> Strings Extracting substrings: ruby> herb = "parsley" "parsley" ruby> herb[0,1] o/p => "p" ruby> herb[-2,2] "ey" ruby> herb[0..3] "pars" ruby> herb[-5..-2] "rsle" Strings Testing for equality:

● ruby> "foo" == "foo" ● true

● ruby> "foo" == "bar"

● false Puzzle guess the word, # save this as guess.rb words = ['foobar', 'baz', 'quux'] secret = words[rand(3)] print "guess? " while guess = STDIN.gets

guess.chop!

if guess == secret

puts "You win!"

break

else

puts "Sorry, you lose."

end

print "guess? " end puts "The word was ", secret, "." Puzzle guess the word,

$ruby guess.rb guess? foobar Sorry, you lose. guess? quux Sorry, you lose. guess? ^D The word was baz. Arrays

●The Array class is one of Ruby’s built-in classes. ●Arrays are compact, ordered collections of objects. ●Ruby arrays can hold objects such as String, Integer,Hash, Symbol, even otherArray objects—you name it. ●Any object that Ruby can create, it can hold in an array. Arrays

●You can create an array by listing some items within square brackets ([]) and separating them with commas. Ruby's arrays can accommodate diverse object types.

●ruby> ary = [1, 2, "3"] ● [1, 2, "3"] Arrays

●Arrays can be concatenated or repeated just as strings can. ●ruby> ary + ["foo", "bar"] ● [1, 2, "3", "foo", "bar"] ●ruby> ary * 2 ● [1, 2, "3", 1, 2, "3"] Arrays ary = [1, 2, "3"] ruby> ary[-2] 2 ruby> ary[-2,2] [2, "3"] ruby> ary[-2..-1] [2, "3"] Arrays

● Arrays can be converted to and from strings, using join and split respectively: ruby> str = ary.join(":") "1:2:3" ruby> str.split(":") ["1", "2", "3"] Arrays

● We could, therefore, create an uninitialized array using the new method of the Array class: ● days_of_week = Array.new ● days_of_week.empty?

● => true ● days_of_week = Array.new(7) ● => [nil, nil, nil, nil, nil, nil, nil] Arrays

Populating an Array with Data

● Having created an array we need to add some data to it. One way to do this is to place the same data in each element during the created process:

● days_of_week = Array.new(7, "today")

● => ["today", "today", "today", "today", "today", "today", "today"]

● Another option is to use the [] method of the Array class to specify the elements one by one:

● days_of_week = Array[ "Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun" ]

● => ["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"] Hashes

A hash is an unordered collection of key-value pairs that look like this: "storm" => "tornado". ● An associative array has elements that are accessed not by sequential index numbers, but by keys which can have any sort of value. ● Such an array is sometimes called a hash or dictionary; ● A hash can be constructed by quoting pairs of items within curly braces ({}). ● You use a key to find something in a hash, much as you use an index to find something in an array. Hashes

● ruby> h = {1 => 2, "2" => "4"} ● {1=>2, "2"=>"4"} ● ruby> h[1] ● 2 ● ruby> h["2"] ● "4" ● ruby> h[5] ● nil ● ruby> h[5] = 10 # appending an entry ● 10 Hashes

● ruby> h ● {5=>10, 1=>2, "2"=>"4"} ● ruby> h.delete 1 # deleting an entry by key ● 2 ● ruby> h[1] ● nil ● ruby> h ● {5=>10, "2"=>"4"} Creating Hashes

● Like arrays,there are a variety of ways to create hashes.You can create an empty hash with the new class method. irb(main):014:0> month=Hash.new => {} irb(main):015:0> month.empty? => true irb(main):016:0> month.length => 0 irb(main):017:0> month.size => 0 Creating Hashes

You can also use new to create a hash with a default value— which is otherwise just nil—like this: irb(main):018:0> months = Hash.new( "month" ) => {} irb(main):019:0> months[0] => "month" irb(main):020:0> months => {} irb(main):021:0> months = Hash.new( "month" ) or like this: months = Hash.new "month" Creating Hashes

● When you access any key in a hash that has a default value, if the key or value doesn’t exist, accessing the hash will return the default value: months[0] or: months[72] or: months[234] # => "month" Creating Hashes

● When you access any key in a hash that has a default value, if the key or value doesn’t exist, accessing the hash will return the default value: months[0] or: months[72] or: months[234]

# => "month" Basic I/O

# irb(main):060:0> noun => "was" irb(main):061:0> noun.chomp => "was" irb(main):062:0> noun.chop! => "wa" irb(main):063:0> noun => "wa" irb(main):064:0> Basic I/O

# Get the parts of speech print "Please enter a past-tense verb: " verb = gets.chomp print "Please enter a noun: " noun = gets.chomp print "Please enter a proper noun: " prop_noun = gets.chomp print "Please enter a an adverb: " adv = gets.chomp # Make the sentence. print "#{prop_noun} got a #{noun} and\n#{verb} #{adv} around the block.\n" Basic I/O print "Triangle height: " h = gets.to_f; print "Triangle width: " w = gets.to_f; area = 0.5*h*w print "Triangle height ", h, " width ", w, " has area ", area, "\n" Control Structure

Pick a random number. rno = rand(100) + 1 print "Your magic number is ", rno, "\n" # Perform all sort of totally uselss test on it and report the results. if rno % 2 == 1 then print "Ooooh, that's an odd number.\n" else print "That's an even number.\n" if rno > 2 then print "It's not prime, BTW.\n" end end Control Structure

if rno > 50 print "That's more than half as big as it could be!\n" elsif rno == 42 print "That's the ultimate magic number!!!!\n" elsif rno < 10 print "That's pretty small, actually.\n" else print "What a boring number.\n" end if rno == 100 then print "Gosh, you've maxxed out!\n" end IF...ELSE

● This is the conventional use of the if in perl. ● Notice that there is no need for curly braces ({ and }). ● The body of the if ends with the appropriate keyword, end, else or elsif. ● The then word is generally optional, though you need it if you want to put start the body on the same line as the if, the way the last statement does. ● As in most languages (excluding Python), indenting is not required, and is ignored by the interpreter. ● Of course, it is wise to indent in a way which reflects the structure of the code. IF...ELSE

● # Let the user guess. ● print "Enter heads or tails? " ● hort = gets.chomp ● unless hort == 'heads' || hort == 'tails' ● print "I _said_ heads or tails. Can't you read?\n" ● exit(1) ● end IF...ELSE

● # Now toss the coin. ● toss = if rand(2) == 1 then ● "heads" ● else ● "tails" ● end ● # Report. ● print "Toss was ", toss, ".\n" ● print "You Win!\n" if hort == toss IF...ELSE

● Some more amazing about if: ● The unless keyword is like if, but uses the opposite sense of the test: The code is run if the test is false. ● As with many things in Ruby, if may look like a statement, but it is actually an expression, with a return value. ● The if has a postfix form where the condition comes last. This works with unless as well. Loops

# Some counting with a while. a = 0 while a < 15 print a, " " if a == 10 then print "made it to ten!!" end a = a + 1 end print "\n" Loops

# Here's a way to empty an array. joe = [ 'eggs.', 'some', 'break', 'to', 'Have' ] print(joe.pop, " ") while joe.size > 0 print "\n" Loops

# Simple for loop using a range. for i in (1..4) print i," " end print "\n" for i in (1...4) print i," " end print "\n" Loops # Running through a list (which is what they do). items = [ 'Mark', 12, 'goobers', 18.45 ] for it in items print it, " " end print "\n"

# Go through the legal subscript values of an array. for i in (0...items.length) print items[0..i].join(" "), "\n" end Case for i in (1..10) rno = rand(100) + 1 msg = case rno when 42: "The ultimate result." when 1..10: "Way too small." when 11..15,19,27: "Sorry, too small" when 80..99: "Way to large" when 100: print "TOPS\n" "Really way too large" else "Just wrong" end print "Result: ", rno, ": ", msg, "\n" end Methods / Functions

# Square the number def sqr(x) return x*x end # See how it works. (rand(4) + 2).times { a = rand(300) print a,"^2 = ", sqr(a), "\n" } print "\n" Methods / Functions

# Don't need a parm. def boom print "Boom!\n" end boom boom Methods / Functions

# Default parms print "\n" def line(cnt, ender = "+", fill = "-") print ender, fill * cnt, ender, "\n" end line(8) line(5,'*') line(11,'+','=') Methods / Functions

# Do they change? def incr(n) n = n + 1 end a = 5 incr(a) print a,"\n" Methods / Functions

# Do they change? def incr(n) n = n + 1 end a = 5 incr(a) print a,"\n" Blocks

● A block consists of chunks of code.

● You assign a name to a block.

● The code in the block is always enclosed within braces ({}).

● A block is always invoked from a function with the same name as that of the block. ● This means that if you have a block with the name test, then you use the function test to invoke this block.

● You invoke a block by using the yield statement. Blocks Syntax

Syntax: block_name{ statement1 statement2 ...... } Blocks yield

#!/usr/bin/ruby def test puts "You are in the method" yield puts "You are again back to the method" yield end test {puts "You are in the block"}

O/p You are in the method You are in the block You are again back to the method You are in the block Blocks yield

def test yield 5 puts "You are in the method test" yield 100 end test {|i| puts "You are in the block #{i}"}

O/p

You are in the block 5 You are in the method test You are in the block 100 Blocks yield

Here, the yield statement is written followed by parameters. You can even pass more than one parameter.

In the block, you place a variable between two vertical lines (||) to accept the parameters. Therefore, in the preceding code, the yield 5 statement passes the value 5 as a parameter to the test block. test {|i| puts "You are in the block #{i}"}

Here, the value 5 is received in the variable i. Now, observe the following puts statement: puts "You are in the block #{i}" Blocks yield If you want to pass more than one parameters, then the yield statement becomes: yield a, b and the block is: test {|a, b| statement}

Blocks and Methods def test yield end test{ puts "Hello world"} Blocks yield

if the last argument of a method is preceded by &, then you can pass a block to this method and this block will be assigned to the last parameter. In case both * and & are present in the argument list, & should come later.

#!/usr/bin/ruby def test(&block) block.call end test { puts "Hello World!"} This will produce the following result:

Hello World! BEGIN and END Blocks

Every Ruby source file can declare blocks of code to be run as the file is being loaded (the BEGIN blocks) and after the program has finished executing (the END blocks).

BEGIN { # BEGIN block code puts "BEGIN code block" }

END { # END block code puts "END code block" } # MAIN block code puts "MAIN code block" BEGIN and END Blocks

A program may include multiple BEGIN and END blocks. BEGIN blocks are executed in the order they are encountered. END blocks are executed in reverse order.

When executed, above program produces the following result:

BEGIN code block MAIN code block END code block Modules and Mixins

● Modules are a way of grouping together methods, classes, and constants. ● Modules give you two major benefits.

● Modules provide a namespace and prevent name clashes.

● Modules implement the mixin facility.

● Modules define a namespace, a sandbox in which your methods and constants can play without having to worry about being stepped on by other methods and constants. Modules and Mixins

Syntax: module Identifier statement1 statement2 ...... end ● Module constants are named just like class constants, with an initial uppercase letter. The method definitions look similar, too: Module methods are defined just like class methods. ● As with class methods, you call a module method by preceding its name with the module's name and a period, and you reference a constant using the module name and two colons. Modules and Mixins

Example: # Module defined in trig.rb file module Trig PI = 3.141592654 def Trig.sin(x) # .. end def Trig.cos(x) # .. end end Like class methods, whenever you define a method in a module, you specify the module name followed by a dot and then the method name. Modules and Mixins

We can define one more module with same function name but different functionality:

# Module defined in moral.rb file module Moral VERY_BAD = 0 BAD = 1 def Moral.sin(badness) # ... end end require Statement

The require statement is similar to the include statement of C and C++ and the import statement of Java. If a third program wants to use any defined module, it can simply load the module files using the Ruby require statement:

Syntax: require filename Here, it is not required to give .rb extension along with a file name. require Statement

Syntax: require filename Here, it is not required to give .rb extension along with a file name. Example: $LOAD_PATH << '.' require 'trig.rb' require 'moral' y = Trig.sin(Trig::PI/4) wrongdoing = Moral.sin(Moral::VERY_BAD) require Statement

Here we are using $LOAD_PATH << '.' to make Ruby aware that included files must be searched in the current directory.

If you do not want to use $LOAD_PATH then you can use require_relative to include files from a relative directory. include Statement

You can embed a module in a class. To embed a module in a class, you use the include statement in the class:

Syntax: include modulename If a module is defined in a separate file, then it is required to include that file using require statement before embedding module in a class. include Statement

Consider following module written in support.rb file. module Week FIRST_DAY = "Sunday" def Week.weeks_in_month puts "You have four weeks in a month" end def Week.weeks_in_year puts "You have 52 weeks in a year" end end include Statement d1=Decade.new puts Week::FIRST_DAY Week.weeks_in_month Week.weeks_in_year d1.no_of_months

This will produce the following result:

Sunday You have four weeks in a month You have 52 weeks in a year Sunday 120 Mixins

When a class can inherit features from more than one parent class, the class is supposed to show multiple inheritance.

Ruby does not support multiple inheritance directly but Ruby Modules have another wonderful use. At a stroke, they pretty much eliminate the need for multiple inheritance, providing a facility called a mixin.

Mixins give you a wonderfully controlled way of adding functionality to classes. However, their true power comes out when the code in the mixin starts to interact with code in the class that uses it. Mixins module A def a1 end def a2 end end module B def b1 end def b2 end end Mixins class Sample include A include B def s1 end end samp=Sample.new samp.a1 samp.a2 samp.b1 samp.b2 samp.s1 Mixins

● Module A consists of the methods a1 and a2. ● Module B consists of the methods b1 and b2. ● The class Sample includes both modules A and B. ● The class Sample can access all four methods, namely, a1, a2, b1, and b2. ● Therefore, you can see that the class Sample inherits from both the modules. ● Thus, you can say the class Sample shows multiple inheritance or a mixin. Date & Time

Getting Current Date and Time: Following is the simple example to get current date and time: time1 = Time.new puts "Current Time : " + time1.inspect

# Time.now is a synonym: time2 = Time.now puts "Current Time : " + time2.inspect

[3] pry(main)> t2=Time.now => 2016-04-21 06:35:10 +0530 [4] pry(main)> t2.inspect => "2016-04-21 06:35:10 +0530" Iterators

● The verb iterate means to do the same thing many times, you know, so an iterator is something that does the same thing many times. ● Ruby's String type has some useful iterators: ● irb(main):001:0> "abc".each_byte{|c| printf "<%c>", c}; print "\n"

● => nil ● each_byte is an iterator for each character in the string. Each character is substituted into the local variable c. Iterators

● This can be translated into something that looks a lot like C code ...

● ruby> s="abc";i=0 ● 0 irb(main):006:0> while i printf "<%c>", s[i]; i+=1 irb(main):008:1> end; print "\n" => nil Iterators

● Another iterator of String is each_line. irb(main):048:0> "a\n b\n c\n".each_line{ |l| print l} a b c => "a\n b\n c\n" Iterators

● The verb iterate means to do the same thing many times, you know, so an iterator is something that does the same thing many times.

# Here's a different way to add up an array. fred = [ 4, 19, 3, 7, 32 ] sum = 0 fred.each { |i| sum += i } print "Sum of [", fred.join(" "), "] is #{sum}\n" Iterators

◆Ruby iterators are methods which take and run a block of code. ◆ The block can be delimited by curly braces or by the keywords do and end. ◆The brackets have higher precedence, and variables declared in them are destroyed. ◆The parameter names for the block are listed between ' | ' symbols at the start of the block. This syntax is borrowed from Smalltalk. Iterators

# Or create a secret message. key = { 'A' => 'U', 'B' => 'Q', 'C' => 'A', 'D' => 'F', 'E' => 'D', 'F' => 'K', 'G' => 'P', 'H' => 'W', 'I' => 'N', 'J' => 'L', 'K' => 'J', 'L' => 'M', 'M' => 'S', 'N' => 'V', 'O' => 'Y', 'P' => 'O', 'Q' => 'Z', 'R' => 'T', 'S' => 'E', 'T' => 'I', 'U' => 'X', 'V' => 'B', 'W' => 'G', 'X' => 'H','Y' => 'R', 'Z' => 'C' } Iterators print "\nThe encoded message is: " "The secret message".each_byte do | b | b = b.chr.upcase if key.has_key?(b) then print key[b] else print b end end print "\n" Iterators

# But give us the info to read print ", " it anyway. end print "The key is: " ct = ct + 1 ct = 8 key.each { | k, v | print "#{v} => #{k}" if ct == 8 then } print "\n " print "\n\n" ct = 0 else

Iterators

# Some interesting things from Integer. 3.times { print "Hi! " } print "\n" print "Count: " 3.upto(7) { |n| print n, " " } print "\n" Ranges

● Ranges are composed of expr..expr or expr...expr. Two dots includes the last element, three dots excludes it. ● irb(main):051:0> ('a'..'g').each{ | letter| puts letter } ● irb(main):052:0> (1...3).each{ |num| puts num } ● 1 ● 2

● Produces only two numbers since "..." does not include the last element. File I/O

The File.new Method: You can create a File object using File.new method for reading, writing, or both, according to the mode string. Finally, you can use File.close method to close that file.

Syntax: aFile = File.new("filename", "mode") # ... process the file aFile.close File I/O

The File.open Method: You can use File.open method to create a new file object and assign that file object to a file. However, there is one difference in between File.open and File.new methods. The difference is that the File.open method can be associated with a block, whereas you cannot do the same using the File.new method.

File.open("filename", "mode") do |aFile| # ... process the file end File I/O

Modes Description r Read-only mode. The file pointer is placed at the beginning of the file. This is the default mode. r+ Read-write mode. The file pointer will be at the beginning of the file. w Write-only mode. Overwrites the file if the file exists. If the file does not exist, creates a new file for writing. w+ Read-write mode. Overwrites the existing file if the file exists. If the file does not exist, creates a new file for reading and writing. a Write-only mode. The file pointer is at the end of the file if the file exists. That is, the file is in the append mode. If the file does not exist, it creates a new file for writing. a+ Read and write mode. The file pointer is at the end of the file if the file exists. The file opens in the append mode. If the file does not exist, it creates a new file for reading and writing. File I/O Reading and Writing Files:

gets reads a line from standard input, and aFile.gets reads a line from the file object aFile. However, I/O objects provides additional set of access methods to make our lives easier. The sysread Method: You can use the method sysread to read the contents of a file. You can open the file in any of the modes when using the method sysread. For example : Following is the input text file: This is a simple text file for testing purpose. File I/O

#!/usr/bin/ruby aFile = File.new("input.txt", "r") if aFile content = aFile.sysread(20) puts content else puts "Unable to open file!" end

This statement will output the first 20 characters of the file. The file pointer will now be placed at the 21st character in the file. File I/O

The each_byte Method:The method each_byte is always associated with a block. Consider the following code sample: aFile = File.new("input.txt", "r+") if aFile aFile.syswrite("ABCDEF") aFile.each_byte {|ch| putc ch; putc ?. } else puts "Unable to open file!" end Characters are passed one by one to the variable ch and then displayed on the screen as follows: s. .a. .s.i.m.p.l.e. .t.e.x.t. .f.i.l.e. .f.o.r. .t.e.s.t.i.n.g. .p.u.r.p.o.s.e... File I/O

The syswrite Method: Write the contents into a file. You need to open the file in write mode when using the method syswrite. For example: #!/usr/bin/ruby aFile = File.new("input.txt", "r+") if aFile aFile.syswrite("ABCDEF") else puts "Unable to open file!" end This statement will write "ABCDEF" into the file. File I/O

The IO.readlines Method: The class File is a subclass of the class IO. The class IO also has some methods, which can be used to manipulate files.

One of the IO class methods is IO.readlines. This method returns the contents of the file line by line. The following code displays the use of the method IO.readlines: arr = IO.readlines("input.txt") puts arr[0] puts arr[1] File I/O

The IO.foreach Method: This method also returns output line by line. The difference between the method foreach and the method readlines is that the method foreach is associated with a block. However, unlike the method readlines, the method foreach does not return an array. For example:

IO.foreach("input.txt"){|block| puts block} This code will pass the contents of the file test line by line to the variable block, and then the output will be displayed on the screen. File I/O

Renaming and Deleting Files: Example to rename an existing file test1.txt: # Rename a file from test1.txt to test2.txt File.rename( "test1.txt", "test2.txt" ) Following is the example to delete an existing file test2.txt:

# Delete file test2.txt File.delete("test2.txt") File I/O

File Modes and Ownership: Use the chmod method with a mask to change the mode or permissions/access list of a file:

Following is the example to change mode of an existing file test.txt to a mask value: file = File.new( "test.txt", "w" ) file.chmod( 0755 ) Exceptions

● The execution and the exception always go together. If you are opening a file, which does not exist, then if you did not handle this situation properly, then your program is considered to be of bad quality.

● The program stops if an exception occurs. So exceptions are used to handle various type of errors, which may occur during a program execution and take appropriate action instead of halting program completely.

● Ruby provide a nice mechanism to handle exceptions. We enclose the code that could raise an exception in a begin/end block and use rescue clauses to tell Ruby the types of exceptions we want to handle. Exceptions

Syntax : begin # - rescue OneTypeOfException # - rescue AnotherTypeOfException # - else # Other exceptions ensure # Always will be executed end Exceptions

● Everything from begin to rescue is protected. If an exception occurs during the execution of this block of code, control is passed to the block between rescue and end.

● For each rescue clause in the begin block, Ruby compares the raised Exception against each of the parameters in turn. The match will succeed if the exception named in the rescue clause is the same as the type of the currently thrown exception, or is a superclass of that exception. Exceptions

● begin

● file = open("/unexistant_file")

● if file

● puts "File opened successfully"

● end

● rescue

● file = STDIN

● end

● print file, "==", STDIN, "\n"

● This will produce the following result. You can see that STDIN is substituted to file because open failed. Exceptions

● Using retry Statement:

● You can capture an exception using rescue block and then use retry statement to execute begin block from the beginning.

● Syntax:

● begin

● # Exceptions raised by this code will

● # be caught by the following rescue clause

● rescue

● # This block will capture all types of exceptions

● retry # This will move control to the beginning of begin

● end Exceptions

#!/usr/bin/ruby begin file = open("/unexistant_file") if file puts "File opened successfully" end rescue fname = "existant_file" retry end Exceptions

The following is the flow of the process:

● an exception occurred at open

● went to rescue. fname was re-assigned

● by retry went to the beginning of the begin

● this time file opens successfully

● continued the essential process. Exceptions

Using raise Statement: You can use raise statement to raise an exception. The following method raises an exception whenever it's called. It's second message will be printed. Program Syntax: raise OR raise "Error Message" OR raise ExceptionType, "Error Message" OR raise ExceptionType, "Error Message" condition Exceptions

The first form simply reraises the current exception (or a RuntimeError if there is no current exception). This is used in exception handlers that need to intercept an exception before passing it on.

The second form creates a new RuntimeError exception, setting its message to the given string. This exception is then raised up the call stack.

The third form uses the first argument to create an exception and then sets the associated message to the second argument.

The fourth form is similar to third form but you can add any conditional statement like unless to raise an exception. Exceptions begin puts 'I am before the raise.' raise 'An error has occurred.' puts 'I am after the raise.' rescue puts 'I am rescued.' end puts 'I am after the begin block.' O/p I am before the raise. I am rescued. I am after the begin block. Exceptions #!/usr/bin/ruby begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect end This will produce the following result:

A test exception. ["main.rb:4"] Exceptions Using ensure Statement: Sometimes, you need to guarantee that some processing is done at the end of a block of code, regardless of whether an exception was raised. For example, you may have a file open on entry to the block and you need to make sure it gets closed as the block exits begin #.. process #..raise exception rescue #.. handle error ensure #.. finally ensure execution #.. This will always execute. end Exceptions

begin raise 'A test exception.' rescue Exception => e puts e.message puts e.backtrace.inspect ensure puts "Ensuring execution" end This will produce the following result:

A test exception. ["main.rb:4"] Ensuring execution Exceptions

begin #.. process #..raise exception rescue # .. handle error else #.. executes if there is no exception ensure #.. finally ensure execution #.. This will always execute. end Exceptions

begin # raise 'A test exception.' puts "I'm not raising exception" rescue Exception => e puts e.message puts e.backtrace.inspect else puts "Congratulations-- no errors!" ensure puts "Ensuring execution" end Exceptions

throw :lablename #.. this will not be executed catch :lablename do #.. matching catch will be executed after a throw is encountered. end OR throw :lablename condition #.. this will not be executed catch :lablename do #.. matching catch will be executed after a throw is encountered. end Exceptions def promptAndGet(prompt) print prompt res = readline.chomp throw :quitRequested if res == "!" return res end Exceptions catch :quitRequested do name = promptAndGet("Name: ") age = promptAndGet("Age: ") sex = promptAndGet("Sex: ") # .. # process information end promptAndGet("Name:")

Name: Ruby on Rails Age: 3 Sex: ! Name:Just Ruby