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: 150 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 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.



2. Select the Platform and check the "I agree to the Java SE Development Kit 6 Licence Agreement".



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 pacakge.

(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_RegularExpression" sample application
  12. Open, build, and run "Ruby_StringClass2" 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 1.class
puts 3.433.class
puts "hello".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 informatuon 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
Fixnum
Float
String
----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 informatuon 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]

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
Sat Jun 28 08:52:08 -0400 2008
----Display size or length of an array
7
7
----Display size or length of an array
54
3.14
Rails

                                                                                                                                                 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"
h1 = { "a" => 100, "b" => 200, "c"=>300, 56 => "Sang Shin" }
puts h1["b"]
puts h1[56]

h2 = Hash["a" => 100, "b" => 200, "c" => 300, 56 => "Sang Shin" ]
puts h2["b"]
puts h2[56]

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
200
Sang Shin
200
Sang Shin
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

  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

                                                                                                                                                 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_RegularExpression" sample application


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

puts "----Regular Expression"
puts   a = "hello there"
puts   a[1]                   #=> "e"
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.12) 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

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


In this exercise,  you are going to learn 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, and then how to add a new method to an existing class such as String class.

  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=() wrtier 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


In this exercise, you are going to learn how Ruby methods can be chained through dot (.) notation.  You are going to learn then how to use define and use class method.  Finally, you are going to learn how a method call actually implemented in Ruby - it is through a send method.

(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_SendMethod" sample application


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

# 2 + 2 is equivalent to 2+(2) and 2.send(:+, 2)
puts 2+2

# The + is basically a method which takes a parameter
puts 2+(2)

# The send method of the Object class
puts 2.send(:+, 2)

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

4
4
4

                                                                                                                                                 return to top of exercise

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


1. Open "RubyMethod_SendMethod" 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
 
  def myhellomethod(name)
    @completegreeting = "#{@greeting} #{name}"
  end
 
end

puts "----Create an object instance of Hello class and call a method of it"
hello_instance = Hello.new("Hello")
puts hello_instance.myhellomethod("Boston!")

puts "----Call the same method using send"
puts hello_instance.send(:myhellomethod, "Boston")

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

----Define Hello class
----Create an object instance of Hello class and call a method of it
Hello Boston!
----Call the same method using send
Hello Boston

                                                                                                                                                 return to top of exercise

Summary

In this exercise, you learned how Ruby methods can be chained through dot (.) notation.  You are going to learn then how to use define and use class method.  Finally, you are going to learn how a method call actually implemented in Ruby - it is through a send method.

                                                                                                                                                           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.

(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

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 are also going to learn how to use module to create mixin's.

                                                                                                                                                           return to the top


Exercise 6: Blocks


In this exercise, you are going to exercise the basic concepts of block. (The feature of Ruby block is one of the differences between Java and Ruby - there is no comparable feature in Java.)  Ruby blocks allow you to encapsulate code and send it to a method for any kind of usage that method wants to use it for.  Any method in Ruby can have a block attached to it.

  1. Open, build, and run "RubyBlock_TwoFormats" sample application
  2. Open, build, and run "RubyBlock_yieldExecuteSuppliedBlock" sample application
  3. Open, build, and run "RubyBlock_yieldWithParameters" sample application
  4. Open, build, and run "RubyBlock_yieldWithParameters2" sample application
  5. Open, build, and run "RubyBlock_Proc" sample application
  6. Open, build, and run "RubyBlock_Proc2" sample application
  7. Open, build, and run "RubyBlock_lambda" sample application


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


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

#
# Block can be represented in two different formats
#
 
puts "----First format of code block containing code fragment between { and }"
[1, 2, 3].each { |n| puts "Number #{n}" }

puts "----Second format of code block containing code fragment between do and end"
[1, 2, 3].each do |n|
  puts "Number #{n}"
end

Explanation of the code: The each is a method of Array class as shown Array Ruby doc.  Just like any method in Ruby, a block can be attached (supplied) to the each method.  The each method calls the block once for each element in self, passing that element as a parameter. This is an example of a built-in method of Ruby language which takes a block.  In the subsequent steps, you are going to define your method which takes a block.

For your own study: Move the mouse to the each and press CTRL+Space and read the document of each method.



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

----First format of code block containing code fragment between { and }
Number 1
Number 2
Number 3
----Second format of code block containing code fragment between do and end
Number 1
Number 2
Number 3

                                                                                                                                                 return to top of exercise

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


In the previous step, you've seen an example in which a built-in method, each, of Array class of Ruby language takes a block.  In this and next steps, you are going to define your own method in uour own class, which takes a block.

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

#
# The goal of this exercise is to see how
# a supplied block is executed through "yield"
# keyword.
#
 
puts "----Define MyClass which invokes yield"
class MyClass
  def command()
    puts "This is a message from the command method of MyClass "
   
    # yield will execute the attached block to the method
    yield()   
  end       
end

puts "----Create object instance of MyClass"
m = MyClass.new

puts "----Call command method of the MyClass passing a block"
m.command {puts "Hello World!"}

puts "----Call command method of the MyClass passing a block"
m.command {puts "Life is good!"}

puts "----Call command method of the MyClass passing a block"
m.command do
  [1, 2, 3].each do |n|
    puts "Number #{n}"
  end
end

puts "----Call command method of the MyClass passing a block"
m.command { [1, 2, 3].each { |n| puts "Number #{n}" } }

Explanation of the code: When command method of the MyClass is invoked, it is attached (or supplied/passed/sent) with a block, for example, {puts "Hello World!"}.  Now this attached block will be executed where the yield() method is called within the command method.  Hence, the result will be

This is a message from the command method of MyClass
Hello World!

For your own study: Move the cursor over yield and press CTRL+Space.



3. Run the project.
4. Study the result.
----Define MyClass which invokes yield
----Create object instance of MyClass
----Call command method of the MyClass passing a block
This is a message from the command method of MyClass
Hello World!
----Call command method of the MyClass passing a block
This is a message from the command method of MyClass
Life is good!
----Call command method of the MyClass passing a block
This is a message from the command method of MyClass
Number 1
Number 2
Number 3
----Call command method of the MyClass passing a block
This is a message from the command method of MyClass
Number 1
Number 2
Number 3

                                                                                                                                                 return to top of exercise

(6.3) Open, build, and run "RubyBlock_yieldWithParameters" sample application


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


puts "----Define MyClass that yields the passed code block"
class MyClass
  def command(my_parameter)
    puts "**Star command says: "
   
    # yield will execute the supplied block with a parameter
    yield(my_parameter)   
  end       
end

puts "----Create an object instance of MyClass"
m = MyClass.new

puts "----Call command method of the MyClass"
m.command(1) {|x| puts "Hello World! is called with number #{x}" }
m.command(2) {|i| puts "Number #{i} is passed."}
m.command(3) {|i| puts "Number #{i} is passed."}
m.command("something") {|x| puts x}
m.command("something") {|t| puts t}

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

----Define MyClass that yields the passed code block
----Create an object instance of MyClass
----Call command method of the MyClass passing a parameter
**Star command says:
Hello World! is called with number 1
**Star command says:
Number 2 is passed.
**Star command says:
Number 3 is passed.
**Star command says:
something
**Star command says:
something

Explanation of the code: The block can take parameters, which are passed from the yield(<parameters>) method.  In this example, the yield(my_parameter) method passes my_parameter as a parameter.  In the block, the passed parameters(or arguments) are represented as variables between the two vertical bars, |<variables>|.

                                                                                                                                                 return to top of exercise


(6.4) Open, build, and run "RubyBlock_yieldWithParameters2" sample application


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

puts "---Define a method called testyield"
def testyield
  yield(1000, "Sang Shin")
  yield("Current time is", Time.now)
end

puts "----Call testyield method"
testyield { |arg1, arg2| puts "#{arg1} #{arg2}" }

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

---Define a method called testyield
----Call testyield method
1000 Sang Shin
Current time is Mon Jun 30 09:14:56 -0400 2008

Explanation of the code: When the yield(1000, "Sang Shin") is invoked within the testyield method, two parameters, 1000 and "Sang Shin" are passed to the block as two arguments, which are represented as arg1 and arg2.



                                                                                                                                                 return to top of exercise

(6.5) Open, build, and run "RubyBlock_Proc" sample application


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

# Proc objects are blocks of code that have been bound to a set
# of local variables. Once bound, the code may be called in
# different contexts and still access those variables.

say_hi = Proc.new { puts "Hello Sydney" }

# Now we can do this
say_hi.call

def do_it
  if block_given?
    yield
  end
end

#execute it
do_it &say_hi

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

Hello Sydney
Hello Sydney

                                                                                                                                                 return to top of exercise

(6.6) Open, build, and run "RubyBlock_Proc2" sample application


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

def gen_times(factor)     
  return Proc.new {|n| n*factor }   
end

times3 = gen_times(3)   
times5 = gen_times(5)

puts times3.call(12)           
puts times5.call(5)
puts times3.call(times5.call(4))  

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

36
25
60

                                                                                                                                                 return to top of exercise

(6.7) Open, build, and run "RubyBlock_lambda" sample application


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

# Equivalent to Proc.new, except the resulting Proc
# objects check the number of parameters passed when
# called.

say_hi = lambda { puts "Hello Sydney" }

# Now we can do this
say_hi.call

def do_it
  if block_given?
    yield
  end
end

#execute it
do_it &say_hi

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

Hello Sydney
Hello Sydney

                                                                                                                                                 return to top of exercise

Summary

In this exercise,  you have learned how to use a block of Ruby language.

                                                                                                                                                 return to the top




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


1. The homework is to write your own Ruby application as following.
2. Send the following files to railshomeworks@sun.com with Subject as RailsHomework-ruby_basics.


                                                                                                                                                 return to the top