Ruby Language Basics

Sang Shin, sang.shin@sun.com, www.javapassion.com/rubyonrails



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 6.1 on your computer, you can skip this exercise.

(0.1) Install JDK 6


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



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.

(0.2) Install NetBeans IDE 6.1


1. Go to NetBeans IDE 6.1 ( download) site using your browser.
2. Click Download NetBeans IDE link.



3. 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.)




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. Open, build, and run "Ruby_StringClass" sample application
  4. Open, build, and run "Ruby_EverythingIsObject" sample application
  5. Open, build, and run "Ruby_ArrayClass" sample application
  6. Open, build, and run "Ruby_Iteration" sample application
  7. Open, build, and run "Ruby_HashClass" sample application
  8. Open, build, and run "Ruby_HashClass_Iteration" sample application
  9. Open, build, and run "Ruby_NamingConvention" sample application
  10. Open, build, and run "Ruby_SymbolClass" sample application
  11. Open, build, and run "Ruby_SymbolClass2" sample application
  12. Open, build, and run "Ruby_RegularExpression" sample application
  13. Open, build, and run "Ruby_StringClass2" sample application
  14. Open, build, and run "Ruby_StringClass_Interpolation" sample application
  15. 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)


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) Open, build, and run "Ruby_StringClass" sample application


1. Open "Ruby_StringClass" sample application.




2. Study the 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
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.4) 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
puts 9.class
puts ["this","is","an","array"].class
hash1 = {:this => "is", :a => "hash"}
puts hash1.class
puts :symbol.class

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

puts '----Display class information of Object class'
puts Object.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
80
----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.5) 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.6) 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.7) 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 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 "----Less 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[: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
Go Fish

                                                                                                                                                 return to top of exercise

(1.8) 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 }

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}" }

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

                                                                                                                                                 return to top of exercise

(1.9) 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.10) 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 myvalue string literals takes different address space"
puts "myvalue".object_id
puts "myvalue".object_id
puts "myvalue".object_id

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

puts "----Verify that the myvalue symbol is the same object"
puts :myvalue.object_id
puts :myvalue.object_id
puts :myvalue.object_id

puts "----Display the class of :symbol object"
puts :myvalue.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 myvalue string literals take a different address space
6
8
10
----Display class of the String object
String
----Verify that the myvalue symbol is the same object
12
12
12
----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.11) 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.12) 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.13) 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.14) 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.15) Open, build, and run "Ruby_Numbers" sample application


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

puts 10
puts 10.class

puts 0.5
puts 0.5.class

puts 2e-4
puts 2e-4.class

puts 0xEFEF
puts 0xEFEF.class

puts 010
puts 010.class

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


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")

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

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

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


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


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"
puts array.uniq.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
7
5
3
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 "---- 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 "Hi"
  end
end

class MyClass
  alias_method :say_hi_orig, :say_hi
   
  def say_hi
    puts "Before say hi"
    say_hi_orig
    puts "After say hi"
  end
end

puts "----Call new say_hi method"
MyClass.new.say_hi

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

----Call new say_hi method
Before say hi
Hi
After say 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


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
  break
}

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

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


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

# Wha? 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