Ruby Language Basics

Sang Shinwww.javapassion.com/rubyonrails



Ruby programming language is 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.   In this lab, you are going to learn basic language features of Ruby.


Expected duration: 200 minutes (excluding homework)




Software Needed

Before you begin, you need to install the following software on your computer.  The installation instruction of JDK and NetBeans is described in  Exercise 0 below.


OS platforms you can use


Change Log


Things to be done (By Sang Shin)


Lab Exercises


Exercise 0: Install JDK and NetBeans IDE


If you have already installed JDK 5 or 6 and NetBeans IDE on your computer, you can skip this exercise.
  1. Install JDK
  2. Install NetBeans IDE

(0.1) Install JDK 6


1. Download JDK Update x (as of Jan. 28th, 2010, the Update 18 is the latest) from the download page by clicking Download button as shown below. 

Note: In this document, JDK and NetBeans are installed separately just for the sake of clarifying what needs to be installed.  But if you have installed neither JDK nor NetBeans, you are welcome to download and install JDK + NetBeans Bundle.



2. Select the Platform - in the example below, Windows platform is selected, for example, and check the "I agree to the Java SE Development Kit 6 License Agreement". Click Continue button.



3. Download the JDK 6 package either directly or using Sun Download Manager.  (Use Sun Download Manager if your network is not reliable.)



4. Save the file in the local file system.



5. Install JDK by running downloaded JDK installation package.


                                                                                                                                              return to top of exercise

(0.2) Install NetBeans IDE


1. Go to NetBeans IDE ( download) site using your browser.
2. Select Ruby or All bundle, which includes Ruby module.  (All bundle is recommended since you are going to use GlassFish app server later in the course as a deployment platform.)




                                                                                                                                              return to top of exercise

Exercise 1: Ruby Language Basics


In this exercise, you are going to learn how to create NetBeans Rub Application project first. You also learn how to use Interactive Ruby Shell (IRB).  You are then going to learn about built-in classes such as String class, Array class, Hash class, Symbol class, etc.
  1. Build and run "Hello World" Ruby application
  2. Try Ruby Shell (IRB)
  3. Try IRB at the command line
  4. Try IRB swing app
  5. Try ri at the command line
  6. Open, build, and run "Ruby_StringClass" sample application
  7. Open, build, and run "Ruby_EverythingIsObject" sample application
  8. Open, build, and run "Ruby_ArrayClass" sample application
  9. Open, build, and run "Ruby_Iteration" sample application
  10. Open, build, and run "Ruby_HashClass" sample application
  11. Open, build, and run "Ruby_HashClass_Iteration" sample application
  12. Open, build, and run "Ruby_NamingConvention" sample application
  13. Open, build, and run "Ruby_SymbolClass" sample application
  14. Open, build, and run "Ruby_SymbolClass2" sample application
  15. Open, build, and run "Ruby_RegularExpression" sample application
  16. Open, build, and run "Ruby_StringClass2" sample application
  17. Open, build, and run "Ruby_StringClass_Interpolation" sample application
  18. Open, build, and run "Ruby_Numbers" sample application

(1.1) Build and run "Hello World" Ruby application


1. Create a new Ruby Application NetBeans project





2. Build and run the project.





3. Modify the main.rb.
#
# To change this template, choose Tools | Templates
# and open the template in the editor.
 

puts "Hello World"
puts "Live your life with passion!"
Modified main.rb



4. Run the application again.




                                                                                                                                              return to top of exercise

(1.2) Try Ruby Shell (IRB) in NetBeans


1. Start Ruby Shell.



2. Type in some Ruby code in the Ruby Shell. 
>> "Hello World!"
=> "Hello World!"
>> "Life is all about passion!"
=> "Life is all about passion!"
>> 2+4
=> 6
>> 'Single quoted Hello World'
=> "Single quoted Hello World"
>>



In the rest of this hands-on lab, the Ruby code is captured in the form of main.rb of a Ruby Application project.  You should be able to type the same Ruby code (without puts since Ruby Shell automatically print things out) in the Ruby Shell and get immediate result.

                                                                                                                                                 return to top of exercise

(1.3) Try Ruby Shell (IRB) at the command line


0. Set JAVA_HOME environment varioable to your JDK location. 
1. cd <NetBeans-Install-Directory>/ruby2/jruby-1.1.4/bin. (If you are using NetBeans 6.5.1)
2. Type jirb or jirb --simple-prompt at the command line.
3. Enter some Ruby statements as shown below.

C:\Program Files\NetBeans 6.5.1\ruby2\jruby-1.1.4\bin>jirb
irb(main):001:0> puts "Life is good!"
Life is good!
=> nil
irb(main):002:0> puts 3+4
7
=> nil
irb(main):003:0> quit




                                                                                                                                    return to top of exercise

(1.4) Try Ruby Shell (IRB) Swing app


1.  cd <NetBeans-Install-Directory>/ruby2/jruby-1.1.4/bin. (If you are using NetBeans 6.5.1)
2. Type jirb_swing.



                                                                                                                                    return to top of exercise

(1.5) Try "ri" at the command line


The "ri" is command line utility that displays the documentation of Ruby classes and their methods.

1. Download and install Ruby.




2. Display list of all the classes for which ri has documentation. 
ri -c

3. Display the documentation of String class.

ri String

4. Display the documentation of String#upcase method.

ri String#upcase


Why NetBeans does not come with "ri".  (Quoted from NetBeans engineer's response on "Why ri is not included in NetBeans")

The JRuby that is bundled with NetBeans ships without a "ri" database for all the builtin libraries. It was excluded because the JRuby shipping with NetBeans is primarily intended as a Ruby interpreter for use with NetBeans, and "ri" isn't used by NetBeans at all. Its functionality is replaced by code completion, ctrl-hover over identifiers, the Open Type dialog (which supports method jumps via "#" as a prefix), etc.    The specific reason for excluding it is that the database takes up a LOT of space. Here's what ri is using on my OSX system for just a few gems that are installed.  Note that NetBeans DOES ship with its own database for this stuff (used for fast pre-indexing etc); it couldn't just use the ri index directly because the ri index does not record enough information.

% cd /usr/lib/ruby
% du -skh `find . -name ri`
 68K    ./1.8/rdoc/ri
2.1M    ./gems/1.8/doc/actionmailer-1.3.3/ri
2.1M    ./gems/1.8/doc/actionmailer-1.3.6/ri
2.4M    ./gems/1.8/doc/actionpack-1.13.3/ri
2.5M    ./gems/1.8/doc/actionpack-1.13.6/ri
504K    ./gems/1.8/doc/actionwebservice-1.2.3/ri
504K    ./gems/1.8/doc/actionwebservice-1.2.6/ri
3.0M    ./gems/1.8/doc/activerecord-1.15.3/ri
3.0M    ./gems/1.8/doc/activerecord-1.15.6/ri
1.4M    ./gems/1.8/doc/activesupport-1.4.2/ri
1.4M    ./gems/1.8/doc/activesupport-1.4.4/ri
556K    ./gems/1.8/doc/acts_as_ferret-0.4.1/ri
 12K    ./gems/1.8/doc/cgi_multipart_eof_fix-2.2/ri
 12K    ./gems/1.8/doc/cgi_multipart_eof_fix-2.5.0/ri
328K    ./gems/1.8/doc/daemons-1.0.7/ri
328K    ./gems/1.8/doc/daemons-1.0.9/ri
124K    ./gems/1.8/doc/fastthread-1.0.1/ri
1.9M    ./gems/1.8/doc/ferret-0.11.4/ri
 64K    ./gems/1.8/doc/gem_plugin-0.2.2/ri
 64K    ./gems/1.8/doc/gem_plugin-0.2.3/ri
280K    ./gems/1.8/doc/highline-1.2.9/ri
652K    ./gems/1.8/doc/hpricot-0.6/ri
1.3M    ./gems/1.8/doc/libxml-ruby-0.3.8.4/ri
728K    ./gems/1.8/doc/mongrel-1.0.1/ri
776K    ./gems/1.8/doc/mongrel-1.1.4/ri
576K    ./gems/1.8/doc/needle-1.3.0/ri
648K    ./gems/1.8/doc/net-sftp-1.1.0/ri
1.8M    ./gems/1.8/doc/net-ssh-1.1.2/ri
904K    ./gems/1.8/doc/rake-0.7.3/ri
1.2M    ./gems/1.8/doc/ruby-openid-1.1.4/ri
348K    ./gems/1.8/doc/ruby-yadis-0.3.4/ri
2.3M    ./gems/1.8/doc/rubygems-0.9.4/ri
2.4M    ./gems/1.8/doc/rubygems-1.0.1/ri
800K    ./gems/1.8/doc/sqlite3-ruby-1.2.1/ri

                                                                                                                                    return to top of exercise


(1.6) Open, build, and run "Ruby_StringClass" sample application


1. Open "Ruby_StringClass" sample application.




2. Study the code.  Please feel free to do your own experimentation by adding/changing code.

puts "----Display string with either double quotes or single quote"
puts "Hello World"
puts 'Hello World'

puts "----Interpolation is allowed only with double quotes"
puts "Current time is #{Time.now}\n This is second line"
puts 'no interpolation "here" #{Time.now} with single quote'

puts "----Display class type of String class"
puts "Hello World".class

puts "----Invoke some methods of String class"
puts "ruby".upcase + " " + "rails".capitalize

puts "----Concatenation examples"
puts "I " << "Love " << "Ruby"
puts "Hello " + "World " + self.to_s  #=> Hello World main
a = "hello "
a << "world"   #=> "hello world"
a.concat(33)   #=> "hello world!"
puts a

puts "----Displaying Passion! 3 times"
puts "Passion! " * 3

puts "----String comparisons"
puts "Comparison Returns -1 if other_str is less than,
                           0 if other_str is equal to,
                          +1 if other_str is greater than str.
If the strings are of different lengths, and the strings are equal when
compared up to the shortest length, then the longer string is considered
greater than the shorter one. In older versions of Ruby, setting $= allowed
case-insensitive comparisons; this is now deprecated in favor of using
String#casecmp. "
puts   "abcdef" <=> "abcde"     #=> 1
puts   "abcdef" <=> "abcdef"    #=> 0
puts   "abcdef" <=> "abcdefg"   #=> -1
puts   "abcdef" <=> "ABCDEF"    #=> 1


3. Build and run the application.



4. Spend some time understanding the result.

----Display string with either double quotes or single quote
Hello World
Hello World
----Interpolation is allowed only with double quotes
Current time is Sat Jun 28 17:29:01 -0400 2008
 This is second line
no interpolation "here" #{Time.now} with single quote
----Display class type of String class
String
----Invoke some methods of String class
RUBY Rails
----Concatenation examples
I Love Ruby
Hello World main
hello world!
----Displaying Passion! 3 times
Passion! Passion! Passion!
----String comparisons
Comparison Returns -1 if other_str is less than,
                           0 if other_str is equal to,
                          +1 if other_str is greater than str.
If the strings are of different lengths, and the strings are equal when
compared up to the shortest length, then the longer string is considered
greater than the shorter one. In older versions of Ruby, setting $= allowed
case-insensitive comparisons; this is now deprecated in favor of using
String#casecmp.
1
0
-1
1

                                                                                                                                                 return to top of exercise


(1.7) Open, build, and run "Ruby_EverythingIsObject" sample application


1. Open "Ruby_EverythingIsObject" sample application as described in step (1.3) above.
2. Study the code.

puts "----Display class information of the various objects"
puts "This is a string".class                         #=> String
puts 9.class                                                 #=> Fixnum
puts ["this","is","an","array"].class             #=> Array
puts ({:this => "is", :a => "hash"}.class)   #=> Hash
puts :my_symbol.class                                #=> Symbol

puts "----Create a new object from MyClass class and then display class information of it"
class MyClass
end
c = MyClass.new
puts c.class

puts '----Display current time and display class information of Time class'
puts Time.now
puts Time.class                                           #=> Class

puts '----Display class information of Object class'
puts Object.class                                        #=> Class

puts '----Display number of methods of Object class'
puts Object.methods.size

puts '----Display methods of Object class in sorted fashion'
puts Object.methods.sort

3. Run the project as described in step (1.3) above.
4. Study the result.

----Display class information of the various objects
String
Fixnum
Array
Hash
Symbol
----Create a new object from MyClass class and then display class information of it
MyClass
----Display current time and display class information of Time class
Sat Jun 28 08:48:03 -0400 2008
Class
----Display class information of Object class
Class
----Display number of methods of Object class
79
----Display methods of Object class in sorted fashion
<
<=
<=>
==
===
=~
>
>=
__id__
__send__
allocate
ancestors
autoload
autoload?
class
class_eval
class_variable_defined?
class_variables
clone
const_defined?
const_get
const_missing
const_set
constants
display
dup
eql?
equal?
extend
extended
freeze
frozen?
hash
id
include?
included
included_modules
inherited
initialize_copy
inspect
instance_eval
instance_exec
instance_method
instance_methods
instance_of?
instance_variable_defined?
instance_variable_get
instance_variable_set
instance_variables
is_a?
kind_of?
method
method_defined?
methods
module_eval
name
new
nil?
object_id
private_class_method
private_instance_methods
private_method_defined?
private_methods
protected_instance_methods
protected_method_defined?
protected_methods
public_class_method
public_instance_methods
public_method_defined?
public_methods
respond_to?
send
singleton_methods
superclass
taint
tainted?
to_a
to_s
type
untaint

                                                                                                                                                 return to top of exercise

(1.8) Open, build, and run "Ruby_ArrayClass" sample application


1. Open "Ruby_ArrayClass" sample application.
2. Study the code.

puts "----An array can contain entries of various types"
a = ["Ruby", 99, 3.14, 'Rails', "Sang Shin"]
puts a

puts "----Assign a value using an index"
a[1] = 54
puts a

puts "----Append an entry to an array"
a << "Rails"
a << Time.now
puts a

puts "----Display size or length of an array"
puts a.size
puts a.length

puts "----Display range of an array"
puts a[1..3]

puts "----Iterate an array"
['apple', 'orange', 'banana'].each {|item| puts item}

puts "----Create a new array using collect"
fruits = ['apple', 'orange', 'banana'].collect {|item| item.upcase}
p fruits

puts "----Call join method"
puts fruits.join(" and ") + " are fruits."

puts "----Union and Difference between arrays"
animals = ['bear', 'monkey', 'cat', 'dog']
domestic_animals = ['cat', 'dog']
p fruits + animals
p fruits + animals - domestic_animals

3. Run the project.
4. Study the result.

----An array can contain entries of various types
Ruby
99
3.14
Rails
Sang Shin
----Assign a value using an index
Ruby
54
3.14
Rails
Sang Shin
----Append an entry to an array
Ruby
54
3.14
Rails
Sang Shin
Rails
Wed Jul 16 13:06:20 -0400 2008
----Display size or length of an array
7
7
----Display range of an array
54
3.14
Rails
----Iterate an array
apple
orange
banana
----Create a new array using collect
["APPLE", "ORANGE", "BANANA"]
----Call join method
APPLE and ORANGE and BANANA are fruits.
----Union and Difference between arrays
["APPLE", "ORANGE", "BANANA", "bear", "monkey", "cat", "dog"]
["APPLE", "ORANGE", "BANANA", "bear", "monkey"]

                                                                                                                                                 return to top of exercise

(1.9) Open, build, and run "Ruby_Iteration" sample application


1. Open "Ruby_Iteration" sample application.
2. Study the code.

puts "----An array can contain entries of various types"
a = ["Ruby", 99, 3.14, "Rails", 'Sang Shin']
puts a

puts "----Iteration of an array"
a.each do |item|
  puts item.class
end

puts "----Another example of Iteration of an array"
countries = ["Korea", "Japan", "China", "Brazil"] 
countries.each do |country|
  puts "My country is " + country
end

puts "----Sort the array before iteration"
countries.sort.each do |country|
  puts "My country is " + country
end

puts "----Sort it in reverse order before iteration"
countries.sort.reverse.each do |country|
  puts "My country is " + country
end

puts "----Iterate a number"
5.times do |num|
  puts num
end

3. Run the project.
4. Study the result.

----An array can contain entries of various types
Ruby
99
3.14
Rails
Sang Shin
----Iteration of an array
String
Fixnum
Float
String
String
----Another example of Iteration of an array
My country is Korea
My country is Japan
My country is China
My country is Brazil
----Sort the array before iteration
My country is Brazil
My country is China
My country is Japan
My country is Korea
----Sort it in reverse order before iteration
My country is Korea
My country is Japan
My country is China
My country is Brazil
----Iterate a number
0
1
2
3
4

                                                                                                                                                 return to top of exercise


(1.10) Open, build, and run "Ruby_HashClass" sample application


1. Open "Ruby_HashClass" sample application.
2. Study the code.

puts "----Define a hash in various ways"

puts "----This is the most common way of defining a hash, typically symbol is used as a key"
h1 = { :a => 100, :b => 200, :c=>300, 56 => "Sang Shin" }
puts h1[:b]
puts h1[56]

puts "----Less common way of defining a hash"
h2 = Hash[:a => 100, :b => 200, :c => 300, 56 => "Sang Shin" ]
puts h2[:b]
puts h2[56]

puts "----Even lesser common way of defining a hash"
h3 = Hash[:a, 100, :b, 200, :c, 300, 56, "Sang Shin"]
puts h3[:b]
puts h3[56]

puts "----Define a hash with default value"
h = Hash.new("Go Fish")
h[:a] = 100
h[:b] = 200
puts h[:a]           #=> 100
puts h[:b]           #=> 200
puts h[:c]           #=> "Go Fish"

3. Run the project.
4. Study the result.

----Define a hash in various ways
----This is most common way of defining a hash, typically symbol is used as a key
200
Sang Shin
----Less common way of defining a hash
200
Sang Shin
----Less common way of defining a hash
200
Sang Shin
----Define a hash with default value
100
200
Go Fish

                                                                                                                                                 return to top of exercise

(1.11) Open, build, and run "Ruby_HashClass_Iteration" sample application


1. Open "Ruby_HashClass_Iteration" sample application.
2. Study the code.

puts "----Define a hash"
h = { :a => 100, :b => 200, :c=>300, 56 => "Sang Shin" }
puts h

puts "----Display keys"
h.each_key {|key| puts key }  # {|key| puts key } defines a chunk of code that gets executed for each key

puts "----Display values"
h.each_value {|value| puts value }

puts "----Display key value pairs"
h.each {|key, value| puts "#{key} is #{value}" }

puts "----Display key value pairs"
h.each_pair {|key, value| puts "#{key} is #{value}" }

puts "----Display methods of Hash class"
puts h.methods.sort

3. Run the project.
4. Study the result.

----Define a hash
a100b200c30056Sang Shin
----Display keys
a
b
c
56
----Display values
100
200
300
Sang Shin
----Display key value pairs
a is 100
b is 200
c is 300
56 is Sang Shin
----Display key value pairs
a is 100
b is 200
c is 300
56 is Sang Shin
----Display methods of Hash class
==
===
=~
[]
[]=
__id__
__send__
all?
any?
class
clear
clone
collect
count
cycle
default
default=
default_proc
delete
delete_if
detect
display
drop
drop_while
dup
each
each_cons
each_key
each_pair
each_slice
each_value
each_with_index
empty?
entries
...

                                                                                                                                                 return to top of exercise

(1.12) Open, build, and run "Ruby_NamingConvention" sample application


1. Open "Ruby_NamingConvention" sample application.
2. Study the code.

# Class name is CamelCase
class MyOwnClass
 
  # Constant is in capital letters
  MY_OWN_CONSTANT = 3.14
   
  # Variables - See 3 different types of variables
  @my_own_instance_variable 
  @@my_own_class_variable = "@@my_own_class_variable"
  $my_own_global_variable = "$my_own_global_variable"
 
  # Instance methid - lower case with underscore
  def my_own_instance_method
   
    my_own_local_variable = "my_own_local_variable"
    puts my_own_local_variable
   
    @my_own_instance_variable = "@my_own_instance_variable"
    puts @my_own_instance_variable
   
    puts @@my_own_class_variable
    puts $my_own_global_variable
   
  end
 
  # Class method
  def self.my_own_class_method
      puts @@my_own_class_variable
  end

end

my_own_instance = MyOwnClass.new
my_own_instance.my_own_instance_method

MyOwnClass.my_own_class_method

3. Run the project.
4. Study the result.

my_own_local_variable
@my_own_instance_variable
@@my_own_class_variable
$my_own_global_variable
@@my_own_class_variable

                                                                                                                                                 return to top of exercise

(1.13) Open, build, and run "Ruby_SymbolClass" sample application


1. Open "Ruby_SymbolClass" sample application.
2. Study the code.

# A Symbol is the most basic Ruby object you can create. It's just a name
# and an internal ID. Symbols are useful because a given symbol name
# refers to the same object throughout a Ruby program. Symbols are more
# efficient than strings. Two strings with the same contents are two
# different objects, but for any given name there is only one Symbol object.
# This can save both time and memory.

puts "----Verify that each my_value string literals takes different address space with different object id"
puts "my_value".object_id
puts "my_value".object_id
puts "my_value".object_id

puts "----Check if string objects refering to the same object"
puts "my_value".equal?("my_value")

puts "----Display class of the String object"
puts "my_value".class

puts "----Verify that the my_value symbol is the same object with the same object id"
puts :my_value.object_id
puts :my_value.object_id
puts :my_value.object_id

puts "----Check if symbol objects refering to the same object"
puts :my_value.equal?(:my_value)

puts "----Display the class of :symbol object"
puts :my_value.class

# Therefore, when do we use a string versus a symbol?
#  * If the contents (the sequence of characters) of the object are important, use a string
#  * If the identity of the object is important, use a symbol

puts "----Create symbol from String objects using either intern or to_sym methods"
puts   "Koala".intern.class        
puts   'cat'.to_sym.class     

3. Run the project.
4. Study the result.

----Verify that each my_value string literals takes different address space with different object id
6
8
10
----Check if string objects refering to the same object
false
----Display class of the String object
String
----Verify that the my_value symbol is the same object with the same object id
12
12
12
----Check if symbol objects refering to the same object
true
----Display the class of :symbol object
Symbol
----Create symbol from String objects using either intern or to_sym methods
Symbol
Symbol

                                                                                                                                                 return to top of exercise

(1.14) Open, build, and run "Ruby_SymbolClass2" sample application


Symbols should be used when you have a case where the same string is used many times in your code.

1. Open "Ruby_SymbolClass2" sample application.
2. Study the code.

puts "----Usage of strings consumes lots of memory because there are 10000 Q1 strings"
10000.times do |x|
  x = { "Q1"=>"a", "Q2"=>"b", "Q3"=>"c", "Q4"=>"d"}
end

puts "----Usage of symbols consumes less memory because there is only one :Q1 symbol"
10000.times do |y|
  y = { :Q1=>"a", :Q2=>"b", :Q3=>"c", :Q4=>"d"}
end

3. Run the project.
4. Study the result.

----Usage of strings consumes lots of memory because there are 10000 Q1 strings
----Usage of symbols consumes less memory because there is only one :Q1 symbol

                                                                                                                                                 return to top of exercise


(1.15) Open, build, and run "Ruby_RegularExpression" sample application


1. Open "Ruby_RegularExpression" sample application.
2. Study the code.

puts "----Regular Expression"
puts   a = "hello there"
puts   a[1]                   #=> 101
puts   a[1,3]                 #=> "ell"
puts   a[1..3]                #=> "ell"
puts   a[-3,2]                #=> "er"
puts   a[-4..-2]              #=> "her"
puts   a[12..-1]              #=> nil
puts   a[-2..-4]              #=> ""
puts   a[/[aeiou](.)\1/]      #=> "ell"
puts   a[/[aeiou](.)\1/, 0]   #=> "ell"
puts   a[/[aeiou](.)\1/, 1]   #=> "l"
puts   a[/[aeiou](.)\1/, 2]   #=> nil
puts   a["lo"]                #=> "lo"
puts   a["bye"]               #=> nil

3. Run the project.
4. Study the result.

----Regular Expression
hello there
101
ell
ell
er
her
nil

ell
ell
l
nil
lo
nil

                                                                                                                                                 return to top of exercise

(1.16) Open, build, and run "Ruby_StringClass2" sample application


1. Open "Ruby_StringClass2" sample application.
2. Study the code.

%w(Live your life with passion!).each do |name|
  puts name
end

%q(Live your life with passion!).each do |name|
  puts name
end


3. Run the project.
4. Study the result.

Live
your
life
with
passion!
Live your life with passion!

                                                                                                                                                 return to top of exercise

(1.17) Open, build, and run "Ruby_StringClass_Interpolation" sample application


1. Open "Ruby_StringClass_Interpolation" sample application.
2. Study the code.

puts "----Interpolation is allowed only with double quotes"
puts "Current time is #{Time.now}"

puts "----No interpolation only with single quote"
puts 'no interpolation "here" #{Time.now} with single quote'

puts "----Interpolation with method invocation"
def default_value_method(count = 2)
  'hello ' * count
end

puts "Interpolation example: #{default_value_method(4)}"

3. Run the project.
4. Study the result.

----Interpolation is allowed only with double quotes
Current time is Sat Jul 12 09:58:48 -0400 2008
----No interpolation only with single quote
no interpolation "here" #{Time.now} with single quote
----Interpolation with method invocation
Interpolation example: hello hello hello hello

                                                                                                                                                 return to top of exercise


(1.18) Open, build, and run "Ruby_Numbers" sample application


1. Open "Ruby_StringClass_Numbers" sample application.
2. Study the code.

puts 10
puts 10.class       #=> Fixnum

puts 0.5
puts 0.5.class      #=> Float

puts 2e-4
puts 2e-4.class     #=> Float

puts 0xEFEF
puts 0xEFEF.class   #=> Fixnum

puts 010
puts 010.class      #=> Fixnum

3. Run the project.
4. Study the result.

10
Fixnum
0.5
Float
0.0002
Float
61423
Fixnum
8
Fixnum

                                                                                                                                                 return to top of exercise

Summary

In this exercise,  you have learne how to create NetBeans Rub Application project first. You also learn how to use Interactive Ruby Shell (IRB).  You are then going to learn about built-in classes such as String class, Array class, Hash class, Symbol class, etc.

                                                                                                                                                           return to the top

Exercise 2: Classes and Objects


Learning points
Tasks to be performed
  1. Open, build, and run "RubyClass_HelloClass" sample application
  2. Open, build, and run "RubyClass_attr_accessor" sample application
  3. Open, build, and run "RubyClass_inheritance" sample application
  4. Open, build, and run "RubyClass_AddMethod" sample application

(2.1) Open, build, and run "RubyClass_HelloClass" sample application


This is an example of how to how to write getter and setter method of an attribute, name attribute, in the example below.

1. Open "RubyClass_HelloClass" sample application.
2. Study the code.

puts "----Define Hello class"
class Hello

  # Constructor - invoked by Hello.new
  def initialize(greeting)
    # Instance variables start with @
    @greeting = greeting
  end
 
  # Reader (getter) method
  def name
    @name
  end
 
  # Writer (setter) method
  def name=(value)
    @name = value
  end
 
  # Create a greeting message
  def my_greeting
    @greeting + ", " + @name + "!"
  end
 
  # Print out a greeting message
  def my_hello_method
    puts "#{@greeting}, #{@name}!"
  end
  
end

puts "----Create an object instance of Hello class"
hello_instance = Hello.new("Hello")     # Instance variable @greeting is now set to "Hello"

puts "----Call name=() writer method to set the value of name attribute"
hello_instance.name = "Sang Shin"

puts "----Invoke my_greeting method"
puts hello_instance.my_greeting         #=> Hello, Sang Shin!

puts "----Invoke my_hello_method method"
hello_instance.my_hello_method          #=> Hello, Sang Shin!

3. Run the project.
4. Study the result.

----Define Hello class
----Create an object instance of Hello class
----Call name=() wrtier method to set the value of name attribute
----Invoke my_greeting method
Hello, Sang Shin!
----Invoke my_hello_method method
Hello, Sang Shin!

                                                                                                                                                 return to top of exercise

(2.2) Open, build, and run "RubyClass_attr_accessor" sample application


1. Open "RubyClass_attr_accessor" sample application.
2. Study the code.

puts "----Define Hello class with attr_accessor"
class Hello

  # attr_accessor can be used instead of reader/writer methods
  attr_accessor :name
 
  # Constructor - invoked by Hello.new
  def initialize(greeting)
    # Instance variables start with @
    @greeting = greeting
  end
 
  # Create a greeting message
  def my_greeting
    @greeting + ", " + @name + "!"
  end
 
  # Print out a greeting message
  def my_hello_method
    puts "#{@greeting}, #{@name}!"
  end
  
end

puts "----Create an object instance of Hello class"
hello_instance = Hello.new("Hello")

puts "----Set the value of name attribute"
hello_instance.name = "Sang Shin"

puts "----Get the value of the name attribute and display"
puts hello_instance.name

puts "----Display greeting"
puts hello_instance.my_greeting

puts "----Invoke my_hello_method method"
hello_instance.my_hello_method

3. Run the project.
4. Study the result.

----Define Hello class with attr_accessor
----Create an object instance of Hello class
----Set the value of name attribute
----Get the value of the name attribute and display
Sang Shin
----Display greeting
Hello, Sang Shin!
----Invoke my_hello_method method
Hello, Sang Shin!

                                                                                                                                                 return to top of exercise

(2.3) Open, build, and run "RubyClass_inheritance" sample application


1. Open "RubyClass_inheritance" sample application.
2. Study the code.

#
# The program shows inheritance relationship
# between Ruby classes.
#
 
# Every class is from Object class
puts "----Define Person class"
class Person
  attr_accessor :name
 
  def initialize(name)
    @name = name
  end
   
  def say_hello
    "Hello #{@name}!"
  end
 
  def say_goodbye
    "Goodbye #{@name}!"
  end
end

puts "----Define Student class, which is a child class of Person class"
class Student < Person
  attr_accessor :school
 
  def initialize(name, school)
    super(name)
    @school = school
  end
 
  def say_hello
    "#{@name} goes to #{@school}!"
  end
end

puts "----Create Person and Student objects"
person1 = Person.new("Sang Shin")
student1 = Student.new("Daniel Shin", "Estabrook School")

puts "----Display name of Person object"
puts person1.name

puts "----Display name and school of Student object"
puts student1.name
puts student1.school

puts "----Call methods of Person and Student objects"
puts person1.say_hello
puts student1.say_hello

puts person1.say_goodbye
puts student1.say_goodbye

3. Run the project.
4. Study the result.

----Define Person class
----Define Student class, which is a child class of Person class
----Create Person and Student objects
----Display name of Person object
Sang Shin
----Display name and school of Student object
Daniel Shin
Estabrook School
----Call methods of Person and Student objects
Hello Sang Shin!
Daniel Shin goes to Estabrook School!
Goodbye Sang Shin!
Goodbye Daniel Shin!

                                                                                                                                                 return to top of exercise

(2.4) Open, build, and run "RubyClass_AddMethod" sample application


One of the very powerful features of Ruby language is that you can add a new method to any class including the classes that come with the Ruby language itself such as String class.

1. Open "RubyClass_AddMethod" sample application.
2. Study the code.

puts "----Add a new method to String class"
class String
  def rot13
    self.tr("A-Ma-mN-Zn-z","N-Zn-zA-Ma-m")
  end
end

puts "----Invoke a new method of String class"
puts "hello world".rot13

3. Run the project.
4. Study the result.

----Add a new method to String class
----Invoke a new method of String class
uryyb jbeyq

                                                                                                                                                 return to top of exercise

Summary

In this exercise,  you have learned how to create a Ruby class, how to create an object from a Ruby class, how to define a new class by subclassing a parent class.

                                                                                                                                                           return to the top

Exercise 3: Methods


Learning points

Tasks to be performed
  1. Open, build, and run "RubyMethod_Chaining" sample application
  2. Open, build, and run "RubyMethod_ClassMethod" sample application
  3. Open, build, and run "RubyMethod_DefaultValueArgument" sample application
  4. Open, build, and run "RubyMethod_VariableArguments" sample application
  5. Open, build, and run "RubyMethod_ArrayToArguments" sample application
  6. Open, build, and run "RubyMethod_HashArgument" sample application
  7. Open, build, and run "RubyMethod_Parentheses" sample application
  8. Open, build, and run "RubyMethod_Bang" sample application
  9. Open, build, and run "RubyMethod_Bang2" sample application
  10. Open, build, and run "RubyMethod_Alias" sample application


(3.1) Open, build, and run "RubyMethod_Chaining" sample application


1. Open "RubyMethod_Chaining" sample application.
2. Study the code.

array = [3, 2, 2, 3, 7, 5]

puts "----Example of method chaining: array.uniq"
puts array.uniq
puts "----Example of method chaining: array.uniq.sort"
puts array.uniq.sort
puts "----Example of method chaining: array.uniq.sort.reverse"
puts array.uniq.sort.reverse
puts "----Example of method chaining: array.sort.reverse"
puts array.sort.reverse

Explanation of the code: In the code above, three methods of Array class, uniq, sort, and reverse, are chained.

3. Run the project.
4. Study the result.

----Example of method chaining: array.uniq
3
2
7
5
----Example of method chaining: array.uniq.sort
2
3
5
7
----Example of method chaining: array.uniq.sort.reverse
7
5
3
2
----Example of method chaining: array.sort.reverse
7
5
3
3
2
2

                                                                                                                                                 return to top of exercise

(3.2) Open, build, and run "RubyMethod_ClassMethod" sample application


1. Open "RubyMethod_ClassMethod" sample application.
2. Study the code.

puts "----Define Person class"
class Person
 
  # Class method is defined with self. prefix
  def self.my_class_method
    puts "This is my own class method"
  end
 
  # Instance method
  def my_instance_method
    puts "This is my own instance method"
  end
 
end

puts "----Use class method without creating an object"
Person.my_class_method

puts "----Create object first before using an instance method"
person = Person.new
person.my_instance_method

3. Run the project.
4. Study the result.

----Define Person class
----Use class method without creating an object
This is my own class method
----Create object first before using an instance method
This is my own instance method

                                                                                                                                                 return to top of exercise

(3.3) Open, build, and run "RubyMethod_DefaultValueArgument" sample application


1. Open "RubyMethod_DefaultValueArgument" sample application.
2. Study the code.

# Function arguments can have default value
def default_value_method(count = 2)
  'hello ' * count
end

puts "---- Call a method using default value"
puts default_value_method()

puts "---- Call a method providing explicit argument"
puts default_value_method(3)

3. Run the project.
4. Study the result.

---- Call a method using default value
hello hello
---- Call a method providing explicit argument
hello hello hello

                                                                                                                                                 return to top of exercise

(3.4) Open, build, and run "RubyMethod_VariableArguments" sample application


1. Open "RubyMethod_VariableArguments" sample application.
2. Study the code.

# Example of variable arguments
def hello(*names)
  "The number of people is #{names.length}. The names of the people are #{names.join(',')}"
end

puts "---- Pass 2 arguments"
puts hello("Mike", "John")

puts "---- Pass 3 arguments"
puts hello("Charles", "YoungAh", "Daniel")

3. Run the project.
4. Study the result.

---- Pass 2 arguments
The number of people is 2. The names of the people are Mike,John
---- Pass 3 arguments
The number of people is 3. The names of the people are Charles,YoungAh,Daniel

                                                                                                                                                 return to top of exercise

(3.5) Open, build, and run "RubyMethod_ArrayToArguments" sample application


1. Open "RubyMethod_ArrayToArguments" sample application.
2. Study the code.

def my_method(*arguments)
  "The number of arguments is #{arguments.length}. The number of people is #{arguments.length}. The arguments are #{arguments.join(',')}"
end

puts "---- Pass an arry as arguments "
puts my_method(*[1, :a, "Sang Shin"])

3. Run the project.
4. Study the result.

---- Pass an arry as arguments
The number of arguments is 3. The number of people is 3. The arguments are 1,a,Sang Shin

                                                                                                                                                 return to top of exercise

(3.6) Open, build, and run "RubyMethod_HashArgument" sample application


1. Open "RubyMethod_HashArgument" sample application.
2. Study the code.

def hello(*names)
  "The number of arguments is #{names.length}."
end

# If the last argument is a Hash, braces { } can be omitted

puts "---- Pass a Hash argument with {} - Hash argument is the last argument "
puts hello("Sang Shin", {:a=>"Good morning!", :b=>"Good afternoon!"})

puts "---- Pass Hash argument without {} - Hash argument is the last argument "
puts hello("Sang Shin", :a=>"Good morning!", :b=>"Good afternoon!")

puts "---- Pass Hash argument without {} - Hash argument is the only argument "
puts hello(:a=>"Good morning!", :b=>"Good afternoon!")

puts "---- Pass last Hash argument with {} - Hash argument is NOT the last argument "
puts hello({:a=>"Good morning!", :b=>"Good afternoon!"}, "Sang Shin")

puts "---- Pass last Hash argument without {} - Hash argument is NOT the last argument - Compile error"
#puts hello(:a=>"Good morning!", :b=>"Good afternoon!", "Sang Shin")  # Compile error

3. Run the project.
4. Study the result.

---- Pass a Hash argument with {} - Hash argument is the last argument
The number of arguments is 2.
---- Pass Hash argument without {} - Hash argument is the last argument
The number of arguments is 2.
---- Pass Hash argument without {} - Hash argument is the only argument
The number of arguments is 1.
---- Pass last Hash argument with {} - Hash argument is NOT the last argument
The number of arguments is 2.
---- Pass last Hash argument without {} - Hash argument is NOT the last argument - Compile error

                                                                                                                                                 return to top of exercise


(3.7) Open, build, and run "RubyMethod_Parentheses" sample application


1. Open "RubyMethod_Parentheses" sample application.
2. Study the code.

def my_method(*arguments)
  "The number of arguments is #{arguments.length}. The number of people is #{arguments.length}. The arguments are #{arguments.join(',')}"
end

puts "---- Pass arguments enclosed with parentheses "
puts my_method(1, "Sang Shin", :c)

puts "---- Pass arguments without parentheses "
puts my_method 1, "Sang Shin", :c

puts "---- Pass arguments without parentheses, last argument is a hash with {} "
puts my_method 3, "Sang Shin", {:a => " loves ", :b => " Young Shin"}

puts "---- Pass arguments without parentheses, last argument is a hash without {} "
puts my_method 3, "Sang Shin", :a => " loves ", :b => " Young Shin"

puts "---- You have to enclose arguments with parentheses if block is attached "
puts my_method(3, "Sang Shin", {:a => " loves ", :b => " Young Shin"}) {|s| puts s}
# puts my_method 3, "Sang Shin", {:a => " loves ", :b => " Young Shin"} {|s| puts s} # Compile error

puts "---- You have to enclose arguments with parentheses if block is attached "
puts my_method(3, "Sang Shin", :a => " loves ", :b => " Young Shin") {|s| puts s}

3. Run the project.
4. Study the result.

C:\handsonlabs\ruby_basics\samples\RubyMethod_Parentheses\lib\main.rb:9 warning: parenthesize argument(s) for future version
C:\handsonlabs\ruby_basics\samples\RubyMethod_Parentheses\lib\main.rb:12 warning: parenthesize argument(s) for future version
C:\handsonlabs\ruby_basics\samples\RubyMethod_Parentheses\lib\main.rb:15 warning: parenthesize argument(s) for future version
---- Pass arguments enclosed with parentheses
The number of arguments is 3. The number of people is 3. The arguments are 1,Sang Shin,c
---- Pass arguments without parentheses
The number of arguments is 3. The number of people is 3. The arguments are 1,Sang Shin,c
---- Pass arguments without parentheses, last argument is a hash with {}
The number of arguments is 3. The number of people is 3. The arguments are 3,Sang Shin,a loves b Young Shin
---- Pass arguments without parentheses, last argument is a hash without {}
The number of arguments is 3. The number of people is 3. The arguments are 3,Sang Shin,a loves b Young Shin
---- You have to enclose arguments with parentheses if block is attached
The number of arguments is 3. The number of people is 3. The arguments are 3,Sang Shin,a loves b Young Shin
---- You have to enclose arguments with parentheses if block is attached
The number of arguments is 3. The number of people is 3. The arguments are 3,Sang Shin,a loves b Young Shin

                                                                                                                                                 return to top of exercise


(3.8) Open, build, and run "RubyMethod_Bang" sample application


1. Open "RubyMethod_Bang" sample application.
2. Study the code.

# In Ruby, methods that end with an exclamation mark (also called a "bang")
# modify the object. For example, the method upcase! changes the letters of
# a String to uppercase.

name = "Sang Shin"

puts "----Display the name variable in upper case - name is not changed, however"
puts name.upcase
puts name

puts "----Display the name variable in upper case with ! - name is changed"
puts name.upcase!
puts name

3. Run the project.
4. Study the result.

----Display the name variable in upper case - name is not changed, however
SANG SHIN
Sang Shin
----Display the name variable in upper case with ! - name is changed
SANG SHIN
SANG SHIN

                                                                                                                                                 return to top of exercise

(3.9) Open, build, and run "RubyMethod_Bang2" sample application


1. Open "RubyMethod_Bang2" sample application.
2. Study the code.

array = [3, 2, 6, 7, 5]

puts "----Display array in sorted order - array is not changed, however"
print array.sort, "\n"
print array, "\n"

puts "----Display array in sorted order with ! - array is changed"
print array.sort!, "\n"
print array, "\n"

3. Run the project.
4. Study the result.

----Display array in sorted order - array is not changed, however
23567
32675
----Display array in sorted order with ! - array is changed
23567
23567

                                                                                                                                                 return to top of exercise


(3.10) Open, build, and run "RubyMethod_Alias" sample application


1. Open "RubyMethod_Alias" sample application.
2. Study the code.

class MyClass
  def say_hi
    puts "Old Hi"
  end
end

# MyClass is overridden with a new say_hi method.
class MyClass
  # alias_method( newID, oldID )
  #   Makes newID a new copy of the method oldID. This can be used to retain access
  #   to methods that are overridden.
  alias_method :say_hi_orig, :say_hi
   
  def say_hi
    puts "New Hi"
  end

  def say_old_hi
    say_hi_orig
  end

end

puts "----Call old say_hi method"
MyClass.new.say_old_hi   #=> Old Hi

puts "----Call new say_hi method"
MyClass.new.say_hi          #=> New Hi

3. Run the project.
4. Study the result.

----Call old say_hi method
Old Hi
----Call new say_hi method
New Hi

                                                                                                                                                 return to top of exercise


Summary

In this exercise, you learned how to use Ruby methods.  

                                                                                                                                                           return to the top

Exercise 4: Variables


In this exercise, you are going to see how type of a variable in Ruby is dynamically set depending on the type of value that is assigned to it.
  1. Open, build, and run "RubyVariable_dynamicTyping" sample application
  2. Open, build, and run "RubyVariable_LocalVariable" sample application
  3. Open, build, and run "RubyVariable_ClassVariable" sample application

(4.1) Open, build, and run "RubyVariable_dynamicTyping" sample application


Note that the same variable a is assigned with values of different types.  In other words, the type of the variable a changes during runtime.

1. Open "RubyVariable_dynamicTyping" sample application.
2. Study the code.

a = 1
puts a.class

a = "hello"
puts a.class

a = /^Hello.*/
puts a.class

a = {1 => "foo", 2 => "bar"}
puts a.class

a = [1, "ein", a]
puts a.class

3. Run the project.
4. Study the result.

Fixnum
String
Regexp
Hash
Array

                                                                                                                                                 return to top of exercise

(4.2) Open, build, and run "RubyVariable_LocalVariable" sample application


1. Open "RubyVariable_LocalVariable" sample application.
2. Study the code.

i0 = 1

loop {
  i1 = 2
  print "1 ", defined?(i0), "\n"      # "i0" was initialized in the ascendant block
  print "2 ", defined?(i1), "\n"      # "i1" was initialized in this block and visible only within this block
  break
}

print "3 ", defined?(i0), "\n"        # "i0 was initialized in this block
print "4 ", defined?(i1), "\n"        # nil; "i1" was visible only within the loop block
print "5 ", defined?(xx), "\n"        # nil

3. Run the project.
4. Study the result.

1 local-variable
2 local-variable(in-block)
3 local-variable
4 nil
5 nil

                                                                                                                                                 return to top of exercise

(4.3) Open, build, and run "RubyVariable_ClassVariable" sample application


For more detailed explanation of this exercise, please read Class and Instance Variables in Ruby tip written by John Nunemaker.

1. Open "RubyVariable_ClassVariable" sample application.
2. Study the code.

# Quoted from http://railstips.org/2006/11/18/class-and-instance-variables-in-ruby
#
# Class variables are easy. Simply create your new class, use
# the @@ to denote the variable as class level and add a getter
# method like so:
class Polygon
  @@sides = 10
  def self.sides
    @@sides
  end
end

puts Polygon.sides # => 10

# The issue with class variables is inheritance.
# Let’s say I want to subclass Polygon with Triangle
# like so:
class Triangle < Polygon
  @@sides = 3
end

puts Triangle.sides # => 3
puts Polygon.sides # => 3

# What? But Polygon’s sides was set to 10? When you set
# a class variable, you set it for the superclass and
# all of the subclasses.

class Rectangle < Polygon
  @@sides = 4
end

puts Polygon.sides # => 4

3. Run the project.
4. Study the result.

10
3
3
4

                                                                                                                                                 return to top of exercise

Summary

In this exercise, you learned how type of a variable is dynamically set depending on the type of value that is assigned to it.

                                                                                                                                                          return to the top


Exercise 5: Modules


In this exercise, you are going to learn how Module is used to provide namespaces for the classes.  You are also going to learn how to use module to create mixin's.
  1. Open, build, and run "RubyModule_Namespace" sample application
  2. Open, build, and run "RubyModule_Mixin1" sample application
  3. Open, build, and run "RubyModule_Mixin2" sample application

(5.1) Open, build, and run "RubyModule_Namespace" sample application


1. Open "RubyModule_Namespace" sample application.
2. Study the code.

# This code shows that the Module is used to provide
# namespace.

puts "----Define People module with Stalk class"
module People
  class Stalk 
    def about
      "I am a person."
    end
  end
end

puts "----Define Plants module with Stalk class"
module Plants
  class Stalk
    def about
      "I am a plant."
    end
  end
end

puts "----Create an instance of Stalk class of People Module"
a = People::Stalk.new

puts "----Call about method of the Stalk class of People Module"
puts a.about

puts "----Create an instance of Stalk class of Plants Module"
b = Plants::Stalk.new

puts "----Call about method of the Stalk class of Plants Module"
puts b.about

3. Run the project.
4. Study the result.

----Define People module with Stalk class
----Define Plants module with Stalk class
----Create an instance of Stalk class of People Module
----Call about method of the Stalk class of People Module
I am a person.
----Create an instance of Stalk class of Plants Module
----Call about method of the Stalk class of Plants Module
I am a plant.

                                                                                                                                                 return to top of exercise

(5.2) Open, build, and run "RubyModule_Mixin1" sample application


1. Open "RubyModule_Mixin1" sample application.
2. Study the code.

puts "----Create Aeronautics module with launch method"
module Aeronautics
  def launch()
    "3, 2, 1 Blastoff!"
  end 
end

puts "----Create RocketShip class which includes Aeronautics module"
class RocketShip
  include Aeronautics
end

puts "----Create RocketShip object and call launch method from the Aeronautics module"
r = RocketShip.new
puts r.launch   

3. Run the project.
4. Study the result.

----Create Aeronautics module with launch method
----Create RocketShip class which includes Aeronautics module
----Create RocketShip object and call launch method from the Aeronautics module
3, 2, 1 Blastoff!

                                                                                                                                                 return to top of exercise

(5.3) Open, build, and run "RubyModule_Mixin2" sample application


1. Open "RubyModule_Mixin2" sample application.
2. Study the code.

puts "----Create Stringify module with stringify method"
module Stringify
  def stringify
    if @value == 1
      "One"
    elsif @value == 2
      "Two"
    elsif @value == 3
      "Three"
    end
  end
end

puts "----Create MyNumber class which includes Stringify module"
class MyNumber
  include Stringify
  def initialize(value)
    @value = value
  end
end

puts "----Create MyNumber object and call stringify method from the Stringify module"
my_number = MyNumber.new(2)
puts my_number.stringify  # Should print Two

3. Run the project.
4. Study the result.

----Create Stringify module with stringify method
----Create MyNumber class which includes Stringify module
----Create MyNumber object and call stringify method from the Stringify module
Two

                                                                                                                                                 return to top of exercise

Summary

In this exercise, you learned how Module is used to provide namespaces for the classes.  You also learned how to use Module to create mixins.

                                                                                                                                                           return to the top


Exercise 6: I/O (Input and Output)


In this exercise, you are going to exercise the basic concepts of Ruby I/O.
  1. Open, build, and run "RubyIO_keyboard" sample application
  2. Open, build, and run "RubyIO_file" sample application

(6.1) Open, build, and run "RubyIO_keyboard" sample application


1. Open "RubyIO_keyboard" sample application.
2. Study the code.

puts "----Type something in the Output window and press Enter key."
puts "    Make sure you click in the Output window first."
what_you_typed_in = gets

puts "----Display what has been typed in."
puts "What you have typed in: " + what_you_typed_in

3. Run the project.




                                                                                                                                                 return to top of exercise

(6.2) Open, build, and run "RubyIO_file" sample application


1. Open "RubyIO_file" sample application.
2. Study the code.

infile = File.new("input.txt", "r")
outfile = File.new("output.txt", "w")

puts "----Read input.txt file and write it to output.txt file"
infile.each do
  |i|
  outfile.write i
end

outfile.close()
infile.close()

puts "----Display output.txt file"
outfile = File.new("output.txt", "r")
outfile.each do
  |i|
  puts i
end

3. Run the project.






4. Study the result.

----Read input.txt file and write it to output.txt file
----Display output.txt file
Life is worth living... with Passion!

                                                                                                                                                 return to top of exercise



Exercise 7: Ruby Control Structure


In this exercise, you are going to learn various control structures of Ruby language.
  1. Open, build, and run "RubyControl_Assignment" sample application
  2. Open, build, and run "RubyControl_TrueFalse" sample application
  3. Open, build, and run "RubyControl_Conditionals" sample application
  4. Open, build, and run "RubyControl_Loops" sample application

(7.1) Open, build, and run "RubyControl_Assignment" sample application


1. Open "RubyControl_Assignment" sample application.
2. Study the code.

puts "----Every assignment returns the assigned value"
puts a = 4       #=> 4

puts "----Assignments can be chained"
puts a = b = 4   #=> 4
puts a+b         #=> 8

puts "----Shortcuts"
puts a += 2      #=> 6
puts a = a + 2   #=> 8

puts "----Parallel assignment"
a, b = b, a
puts a           #=> 4
puts b           #=> 8

puts "----Array splitting"
array = [1,2]
a, b = *array
puts a           #=> 1
puts b           #=> 2

3. Run the project.
4. Study the result.

----Every assignment returns the assigned value
4
----Assignments can be chained
4
8
----Shortcuts
6
8
----Parallel assignment
4
8
----Array splitting
1
2

                                                                                                                                                 return to top of exercise


(7.2) Open, build, and run "RubyControl_TrueFalse" sample application


1. Open "RubyControl_TrueFalse" sample application.
2. Study the code.

def is_true(value)
  value ? true:false
end

puts is_true(false)
puts is_true(nil)
puts is_true(true)
puts is_true(1)
puts is_true(0)
puts is_true([0,1,2])
puts is_true('a'..'z')
puts is_true("")
puts is_true(:a_symbol)

3. Run the project.
4. Study the result.

false
false
true
true
true
true
true
true
true

                                                                                                                                                 return to top of exercise

(7.3) Open, build, and run "RubyControl_Conditionals" sample application


1. Open "RubyControl_Conditionals" sample application.
2. Study the code.

puts "----if/else condition"
if (1 + 1 == 2)
  puts "One plus one is two"
else
  puts "Not a chance!"
end

puts "----if and unless conditions"
puts "Life is good!" if (1 + 1 == 2)
puts "Surprising" unless (1 + 1 == 2)

puts "----? condition"
puts (1 + 1 == 2)?'True':'Not True'

puts "----case/when/then condition"
spam_probability = rand(100)
puts "spam_probability = " + spam_probability.to_s

case spam_probability
when 0...10 then puts "Lowest probability"
when 10...50 then puts "Low probability"
when 50...90 then puts "High Probability"
when 90...100 then puts "Highest probability"
end

3. Run the project.
4. Study the result.

----if/else condition
One plus one is two
----if and unless conditions
Life is good!
----? condition
True
----case/when/then condition
spam_probability = 30
Low probability

                                                                                                                                                 return to top of exercise

(7.4) Open, build, and run "RubyControl_Loops" sample application


1. Open "RubyControl_Loops" sample application.
2. Study the code.

i = 1

puts "---- while loop"
while (i < 10)
  i *= 2
end
puts i          #=> 16

puts "---- while loop 2"
i *= 2 while (i < 100)
puts i         #=> 128

puts "---- while loop with begin/end"
begin
  i *= 2
end while (i < 100)
puts i         #=> 256

puts "---- until"
i *= 2 until ( i >= 1000)
puts i         #=> 1024

puts "---- loop"
loop do
  break i if (i >= 4000)
  i *= 2
end
puts i         #=> 4096

puts "---- times"
4.times do
   i *= 2
end
puts i         #=> 65536

puts "---- array"
r =[]
for i in 0..7
  next if i % 2 == 0
  r << i
end
puts r

puts "----Many things are easier with blocks"
puts (0..7).select { |i| i % 2 != 0}

3. Run the project.
4. Study the result.

---- while loop
16
---- while loop 2
128
---- while loop with begin/end
256
---- until
1024
---- loop
4096
---- times
65536
---- array
1
3
5
7
----Many things are easier with blocks
1
3
5
7

                                                                                                                                                 return to top of exercise


Exercise 8: Ruby Exception Handling


Learning points
Tasks to be performed:
  1. Open, build, and run "RubyException_raise" sample application
  2. Open, build, and run "RubyException_rescue" sample application
  3. Open, build, and run "RubyException_retry" sample application
  4. Open, build, and run "RubyException_structure" sample application

(8.1) Open, build, and run "RubyException_raise" sample application


1. Open "RubyException_raise" sample application.
2. Study the code.

puts "----Set up some test data"
my_array =[ "Sang Shin", "Young Shin"]
i = 5

puts "----Raise an IndexError"
if i >= my_array.size
  raise IndexError, "#{i} >= size (#{my_array.size})"
end

3. Run the project.
4. Study the result.

C:\handsonlabs\ruby_basics\samples\RubyException_raise\lib\main.rb:7: 5 >= size (2) (IndexError)
----Set up some test data
----Raise an IndexError



                                                                                                                                                 return to top of exercise


(8.2) Open, build, and run "RubyException_rescue" sample application


1. Open "RubyException_rescue" sample application.
2. Study the code.

begin
  file = open("nonexistent_file")
rescue
  puts "file not found"
end

3. Run the project.
4. Study the result.

file not found

                                                                                                                                                 return to top of exercise

(8.3) Open, build, and run "RubyException_retry" sample application


1. Open "RubyException_retry" sample application.
2. Verify that the existant_file file is present.



3. Study the code.

# It failed opening a file and substituted another file name
# to fname, then retried. The following is the flow of the process:

#  an exception occured at open
#  went to rescue. The fname was re-substituted
#  by retry went to the beginning of the begin
#  this time open succeeded
#  continued the essential prosess.

fname = "unexistant_file"

begin
  puts "----begin is entered"
  file = open(fname)
  # some code to use file
rescue
  puts "----rescue is entered, provide a correct file name, and retry"
  fname = "existant_file"
  retry
end

4. Run the project.
5. Study the result.

----begin is entered
----rescue is entered, provide a correct file name, and retry
----begin is entered

                                                                                                                                                 return to top of exercise

(8.4) Open, build, and run "RubyException_structure" sample application


1. Open "RubyException_structure" sample application.
2. Study the code.

begin
  # attempt code here
  age = 18
  raise if age < 60
rescue SyntaxError => mySyntaxError
  puts "----1st rescue is entered"
  print "Unknown syntax error. ", mySyntaxError, "\n"
  # error handling specific to problem here
rescue StandardError => myStandardError
  puts "----2nd rescue is entered"
  print "Unknown general error. ", myStandardError, "\n"
  # error handling specific to problem here
else
  # code that runs ONLY if no error goes here
  puts "----else is entered"
ensure
  # code that cleans up after a problem and its error handling goes here
  puts "----ensure is entered"
end

3. Run the project.
4. Study the result.

----2nd rescue is entered
Unknown general error.
----ensure is entered

                                                                                                                                                 return to top of exercise


Homework Exercise (for people who are taking Sang Shin's "Ruby/JRuby/Rails Development online course")


1. The homework is to modify RubyModule_Namespace project above as following.  The goal of this homework is to test your understanding on how Module is used to provide name space for Ruby classes.  (You might want to create a new project by copying the RubyModule_Namespace project.)  You can name the homework project in any way you want but here I am going to call it MyRubyModule_Namespace.
2. Send the following files to railshomeworks@javapassion.com with Subject as RailsHomework-ruby_basics.


                                                                                                                                                 return to the top