Ruby

http://datamapper.org/
http://www.sitepoint.com/new-methods-ruby-2-2/
http://rubysource.com/an-introduction-to-fxruby/
http://rubysource.com/comparing-haskell-and-ruby-part-i/
http://rubysource.com/comparing-ruby-and-haskell-part-ii/

http://www.rubykoans.com/
http://www.rubymotion.com/
http://rubyinstaller.rubyforge.org
http://instantrails.rubyforge.org

Books:
http://www.ruby-doc.org/docs/ProgrammingRuby/
http://learnrubythehardway.org/
http://mislav.uniqpath.com/poignant-guide/

Gem:
http://rubysource.com/polish-your-gems/
http://net.tutsplus.com/tutorials/ruby/gem-creation-with-bundler/
http://rubysource.com/ruby-devs-your-gems-could-screw-you/
http://rubysource.com/crafting-rubies-best-practices-while-cutting-gems/
RubyGems User Guide

Closure:
http://www.sitepoint.com/closures-ruby/

Template engines:
http://slim-lang.com/

Sinatra:
http://sinatra-book.gittr.com/
http://rubysource.com/category/sinatra/
http://rubysource.com/just-do-it-learn-sinatra-i/
http://rubysource.com/just-do-it-learn-sinatra-ii-2/

WebMachine:
https://github.com/seancribbs/webmachine-ruby

EventMachine:
https://github.com/eventmachine/eventmachine/wiki/
https://github.com/eventmachine/eventmachine/
https://github.com/eventmachine/eventmachine/#readme
http://rubyeventmachine.com/
http://eventmachine.rubyforge.org/EventMachine.html
http://www.igvita.com/2008/05/27/ruby-eventmachine-the-speed-demon/
http://www.paperplanes.de/2011/4/25/eventmachine-how-does-it-work.html
http://www.rubyinside.com/eventmachine-slides-3137.html
http://rubylearning.com/blog/2010/10/01/an-introduction-to-eventmachine-and-how-to-avoid-callback-spaghetti/
https://peepcode.com/products/eventmachine

Blogging softwares:
http://schnitzelpress.org/
http://octopress.org/

Jekyll:
https://github.com/mojombo/jekyll
https://github.com/mojombo/jekyll#readme
http://rubysource.com/zero-to-jekyll-in-20-minutes/

Documentation:
http://www.ruby-lang.org/en/documentation/
http://www.ruby-doc.org/

Inside a class, can we have methods with the same name, but different parameter list?

Need research

What are the differences between a function that takes a block and a function that does not take a block?

It appears that a function (two different functions with the same name) can have different form. One can have a block, and one does not have a block. Depending on whether a block was specified (which form was used), different function is invoked, and therefore have different bahavior. How can we define a function with a block, and how can we define a function without a block?

What is Ruby?

Ruby is a dynamic, reflective, general purpose object-oriented programming language that combines syntax inspired by Perl with Smalltalk-like features. Ruby supports multiple programming paradigms, including functional, object-oriented, imperative, and reflection. It also has a dynamic type system and automatic memory management. It is therefore similar in varying respects to Python, Perl, Lisp, etc..

Matsumoto wished to create a language that balanced functional programming with imperative programming. He wants a scripting language that was more powerful than Perl, and more object-oriented than Python.

object-oriented designs, classes with inheritance, mixins, iterators, closures, exception handling, garbage collection.

Ruby is designed for programmer productivity and fund, following the principles of good user interface design. Matsumoto stresses that the system design needs to emphasize human, rather than computer's needs.

Often people, especially computer enginers, focus on the machines. They think, "By doing this, the machine will run faster. By doing this, the machine will run more effectively. By doing this, the machine will something, something, something." They are focusing on machines. But in fact we need to focus on humans, on how humans care about doing programming or operating the applications. We are the masters. They are the slaves.

  1. Object-oriented (everything is an object)
  2. Five levels of scope (global, class, instance, local, and block)
  3. Exception handling
  4. Iterators and closures (based on passing blocks of code)
  5. Native, Perl-like regular expression at the language level
  6. Operator overloading
  7. Automatic garbage collection
  8. Cooperative multi-threading using green threads
  9. Introspection, reflection, and metaprogramming
  10. Large standard libraries
  11. Support dependency injection
  12. Support object runtime alteration
  13. Continuations and generators

Ruby is object-oriented: every data type is an object, including classes and types which many other languages designate as primitives. Every function is a method. Named values (variables) always designate references to object, not the object themselves. Ruby supports inheritance with dynamic dispatch, mixins, and singleton methods (belonging to, and defined for, a single instance rather than being defined on the class). Though Ruby does not support multiple inheritance, classes can import modules as mixins.

Procedural syntax is supported, but all methods defined outside of the scope of a particular object are actually methods of the Object class. Since this class is the parent of every other class, the changes become visible to all classes and objects.

How to invoke the Ruby interactive shell?

irb

How to quit / exit the interactive shell?

Easy. Just type 'quit', 'exit', 'quit()', 'exit()' without the quotes, hit the enter key and that is it. No fuss.

How to execute Ruby script?

ruby filename

Examples:

puts "Hello World!"

# Everything (including literals) is an object, so this works:
-199.abs                              # 199
"ruby is cool".length              # 12
"Rick Astley".index("c")         # 2
"Nice Day Isn't It?".downcase.split(//).sort.uniq.join  # example of chaining and regular expression

puts "What is your favsorite number?"
number = gets.chomp # example of reading from command line
outputnumber = number.to_i + 1
puts outputnumber.to_s + ' is a bigger and better favorite number.'

# There are a variety of methods of defining strings in Ruby.
a = "\nThis is a double quoted string\n"
a = %Q{\nThis is a double quoted string\n}
a = <<BLOCK
This is a multi-line double quoted string
BLOCK
a = %/\nThis is a double quoted string\n/

a = 'This is a single quoted string'
a = %q{This is a single quoted string}

# Constructing and using array:
a = [1, 'hi', 3.14, 1, 2, [4, 5]]    # nested array
p a[2]
p a.[](2)
p a.reverse
p a.flatten.uniq

# Constructing and using associative array:
hash = { :water => 'wet', :fire => 'hot' }
puts hash[:fire]
hash.each_pair do |key, value|
    puts "#{key} is #{value}"
end
hash.delete :water
hash.delete_if {|k,value| value=='hot'}

# Code blocks
{ puts "Hello World!" }
do puts "Hello World!" end

# Parameter-passing a block to be a closure

What are the key things to remember about Ruby?

  1. In Ruby, everything is an object. In Ruby, everything you manipulate will be an object. Even the result of operation on said objects are objects. This is different from C++ and Java where primitive types exist or some statements do not return a value.
  2. In Ruby, everything inherit from Object
  3. String are simply sequences of bytes that represent a sequence of characters. Strings can be formed a number of ways, but the most common is likely to be using a string literal. A string literal is a constant string that is created by enclosing it in single or double quotes.
  4. Variables are not objects but references (or pointers) to objects. References (and, in turn, variables) merely point to objects; they do not hold the actual objects themselves. When you reference a reference, it does not duplicate the object: both references point to the same object. If you want to duplicate the object (i.e. create another copy of the object in another object rather than simply referencing it), you can use the .clone or .dup method on objects which offer it. In Ruby, if you assign a string to a variable A, the variable A is a reference to the string. If you then assign variable A to variable B, variable B is also a reference to the same string. If you alter the string using variable A, the result of that alteration is also visible when you access variable B.
  5. Every class is actually an object which is an instance of the Class class which is in turn derived from the Object class.

What escape sequences are allowed inside a single quoted string?

Only single quote and backslash are allowed.

When to use single quoted strings and when to use double quoted strings?

Single quoted strings are quite silly and have a very limited set of escape sequences they can use (as a matter of fact, only single quote and backslash are allowed) and are typically useless unless performance is a concern for you (and turning double quoted strings to single quoted strings should probably be the last thing you try when improving performance); double quoted strings, on the other hand, offer far more functionality in the way of interpolation. Firstly, they offer far more escape sequences. As noted above, you can use \n to create a newline character, \t to create a tab character, and so on.

Inside a double quoted string, how can we represent an octal value?

\???

Inside a double quoted string, how can we represent a hexadecimal value?

\x??

Inside a double quoted string, how can we represent the value of a ruby expression?

#{???}

where ??? is a ruby expression.

Inside a double quoted string, how can we represent the escape character?

\e

Inside a double quoted string, how can we represent a control character?

\c?
\C-?
\M-?
\M-\C-?

What does "#{"Tora! "*3}" do?

It takes the string "Tora!" and multiply it by 3 (make 3 copies of the string), treat this as a ruby expression inside the outer string.

What is the purpose of the special delimiters %Q and %q?

The way this constructor works is to follow %Q or %q with any non-alphanumeric, non-multibyte character. For example:

%q{Hoagies & grinders!} → Hoagies and grinders!
%Q;#{"Navy beans! "*3}; → Navy beans! Navy beans! Navy beans!

Note that %q acts like a single quoted string and %Q acts like a double quoted string.

Can we use heredoc to create a string in Ruby?

Yes.

You can use heredoc to create a string by specifying a delimiter after a set of « characters to start the string and putting the delimiter on a line of its own to end it. For example:

my_string = <<MY_STRING
This is a simple string that is
pre-formatted, which means that the
way it is formatted here including
tabs and newlines will be duplicated
when I print it out.
MY_STRING

What is the purpose of Fixnum, and what is the purpose of Bignum?

When creating a numeric object, any integer that is between (-230) and (230 - 1) is assigned to an instance of Fixnum and anything else outside that range is assigned to an instance of Bignum; Ruby does this assignment transparently so there is no need to worry which one to use.

In Ruby source code, how can we represent a decimal number?

Integers are created by entering the number you wish to use without quotes.

In Ruby source code, how can we represent a hexadecimal number?

Prefix those hexadecimal number with 0x:

0x5C1

In Ruby source code, how can we represent an octal number?

Prefix those octal number with a zero:

01411

In Ruby source code, how can we represent a binary number?

Prefix those 0 and 1 with 0b.

0b010101101

What does Ruby do with the _ in 1_90_33?

Ruby ignores the underscores. Some people choose to use them in place of commas for larger numbers to enhance readability.

In Ruby source code, how can we represent a decimal number?

Just type the number or prefix the number with 0d.

In Ruby source code, how can we represent a float?

1.5
1.0e5

Each side of the decimal point must contain a number. When using scientific notation, we must place a zero next to the decimal point or Ruby will try to execute a method named e5 on class Fixnum and end up with !NoMethodError.

In Ruby, if a method name contains a question mark at the end, what does it mean?

It indicates that the method will return a boolean value (true or false)

In Ruby, what are those arithmetic operators also known as?

Those operators are really methods.

What is a Range object and how can we create a Range object?

A Range object holds a sequential collection of values, such as all numbers between 1 and 9 or the letters from A to Z. A range is created by placing a series of dots between the lower and upper limit:

age = 48 .. 81

How to create a Range object that excludes the upper limit?

Use three dots instead of two dots.

Ranges can use either two dots, which indicates an inclusive range of all values including the beginning value and the end value, or three dots, which excludes the last value.

Can we compare two range objects?

Yes. We can use the == operator (method) or the eql? method.

Ranges are considered equal if their beginning and end values are the same.

How can we test to see if a range object contain a specific value?

Use the include? method:

age_group.include?(my_age)

The member? method is an alias for the include? method.

What is an array in Ruby?

Array is a built-in collection. Array is an integer-indexed and ordered collection of elements. It is zero-based like C/C++ and Java (the first element is at index 0). Unlike C/C++ and Java, the elements in a Ruby array do not have to be the same type. We also do not have to specify the type of the array before it is initialized for use.

How can we create an array in Ruby?

its_so_empty = []
oh_so_empty = Array.new
hello = ['ni hao', 'bonjour', 'hi', 'howdy']
random_types = [13, 'napkin', (1336 + 1).to_s]

What is the purpose of %w() and %W()?

This is like the Perl's qw() construct, which stand for quoted words. It permits a list of words to be written without being inside quotes. These constructs return an array of words:

my_haiku = %w( my dog digs it here );
my_haiku = %w( he is nice to me & cats );
my_haiku = %W( but he ate #{(2*3)/6} once )

A string wrapped in the %W delimiter acts like a double quoted string: it performs string interpolation and extended escape sequence substitution, but %w delimiter acts just like a single quoted string: it only allows a subset of the escape sequences to be used and does not facilitate interpolation.

How can we add element to an array?

Elements can easily be added to an array by simply assigning a value to a non-existent index:

my_dazzling_array[10] = 11;

If a gap exists between indexes of the last element in the array and the newest added element, Ruby places nil in the empty slots.

If you simply want to add an element to end of an array, then you can use the « operator:

my_dazzling_array << 14;

or use the push() method:

my_dazzling_array.push(15, 16);

or use some form of insert():

my_dazzling_array.insert(-1, 17);

The push method allows you to push one or more elements onto the end of an array; each element should be provided as a parameter to the method. The insert method allows you to insert elements at (the specified index + 1); in the example, I used -1 to add elements to the end of the array (i.e. -1 moves from the end of the array back one element to the last element. Adding an element after the last element would effectively add it to the end.). This method probably is not the best, but it can be used when the same method needs to insert elements at various places in the array (including the end). The « operator allows you to push specified elements on to the end of an existing array; I pluralized element because several of these "appends" can be chained together to add numerous elements to the end of an array. For example:

my_dazzling_array << 20 << 21 << 22;

How to access an element inside an array?

my_dazzling_array[0]

Does Ruby have the concept of an array slice?

Yes.

my_dazzling_array[0..2]

What is the purpose of the at() method of an array?

It is another way to access the element at the specified index:

my_dazzling_array.at(0)

What is the difference between the fetch() method and the at() method of an array?

Another method, fetch, can also operate in this manner, but fetch can also specify a default value to return if the specified index is not found:

my_dazzling_array.fetch(999, "Not found!!")

What is the purpose of the values_at() method of an array?

Yet another method, values_at, can also operate just like at, fetch, and the [] operator, except this method can take a number of indexes to fetch and return as an array:

my_dazzling_array.values_at(0, 1, 2)

What is the purpose of the delete_at() method of an array?

The delete_at method deletes the element at the index specified as a parameter and returns the value of that element:

my_dazzling_array.delete_at(1)

What is the purpose of the delete() method of an array?

The delete() method deletes the given parameter from the array, and returns the value that was deleted.

my_dazzling_array.delete(4)

The delete method offers the option for a "default" value to return if the specified value does not exist in the array:

my_dazzling_array.delete(1337) { "Element Not Exist!" }

How to create a hash in Ruby?

my_hash = { 'Wally Wombat' => 'The Jungle St.',
'Wilma Wombat' => 'The House on the Corner',
'Sam' => 'Notawombat Way', 'Mump' => 13 }

When creating a hash with Hash.new(), how does Ruby interpret the parameter of Hash.new()?

Ruby also offers the new method for creating hashes; the new method for hashes varies slightly than what would be expected. One would expect that parameters provided to new would become the values of a hash, but in this case it takes a single parameter which becomes a default value if a nonexistent key is referenced (or if the default method is called):

new_hash = Hash.new("Not here!");

How to add element to a hash?

my_wombats['Wombie McWombat'] = '123 That Street'

How to access an element inside a hash?

hash_name[key]

Does a hash in Ruby have the pop() and shift() method?

Yes and No.

Hashes do not offer methods like pop in arrays. Hashes offer shift, but it simply returns the first element as an array which contains the key in one element and the value in another; this method and a couple of others are not very useful if you simply want the value of elements. Oh sure, hashes offer a myriad of methods which allow you to do different things with the elements of a hash (i.e. the to_a method which changes the hash to an array, merge to merge two hashes, replace to replace one hash's values with another's values, etc.), but there are not a whole of options when it comes to grabbing elements from a hash.

How can we test to see if a particular key exist in a hash?

my_wombats.has_key?('Wilma Wombat')

How can we test to see if a particular value exist in a hash?

my_wombats.has_value?('Lamps and pandas')

How can we test to see if the hash is empty?

my_wombats.empty?

How to delete an element from a hash?

To delete an element, simply call the delete method and provide the key you wish to delete as a parameter:

my_wombats.delete['Wilma Wombat']

How to delete all elements from a hash?

my_wombats.clear

How can we assign values to variables in one statement?

p1, p2 = 1, 2
rvalue = [1, 2, 3, 4, 5]
a, b = rvalue

What is the value of c in this assignment?

a, (b, c), d = 10, 11, 12, 13

Arrays can also be assigned in parallel in nested assignments ; Ruby is smart enough to pick apart your expressions into individual objects and try to assign them. In this assignment, the value of c is nil. c does not get assigned because it is in an array with b and the corresponding rvalue is not an array. In this case, Ruby assigns the first element the value.

What is the value of c in this assignment?

a, (b, c), d = 10, [11, 12], 13

In this assignment, the value of c is 12.

How can we match a string against a regular expression?

my_string =~ /\sstring\s/

The index of the first match (i.e. an occurrence of a string matching that pattern) is returned.

How to define a method?

A method is defined by entering the 'def' keyword followed by the method name and parameters, followed by the statements that make up the body of the method, and followed by the 'end' keyword:

def my_new_method(param1, param2)
  puts "Hello";
end

What are the conventions on method name?

  1. A method name should, by convention, start with a lowercase letter and preferably be all lowercase.
  2. If it is querying an attribute, it should end in a question mark.
  3. If the method modifies its receiver in place (it modifies the object that call it), then it should end in an exclamation point

When should a method name ends with a question mark?

If it is querying an attribute, it should end in a question mark.

When should a method name ends with an exclamation mark?

If the method modifies its receiver in place (it modifies the object that call it), then it should end in an exclamation point

Can we assign default value to parameters?

Yes

def new_method(a = "This", b = "is", c = "fun")
  puts a + ' ' + b + ' ' + c + '.';
end

new_method('Rails')

Can we have method that accept a variable number of parameters?

Yes.

def print_relation(relation, *names)
  puts "My #{relation} include: #{names.join(', ')}.";
end

print_relation("cousins", "Morgan", "Miles", "Lindsey");

Parameter list can be variable length. By placing an asterisk before the identifier for the last parameter, we turn it into a variable length list (which is actually just an array created from objects you provide)

What is the convention on naming constants and classes?

Ruby thinks that things that start with an uppercase letter are constants and classes.

**When calling a method, do we have to use parentheses?

No. You can call a method without using parantheses but this generally not a good practice unless you are only passing one parameter.

Can a method return more than one values?

Yes.

In the body of our method, if we do not explicitly return a value, what happen?

Methods always return a value. If no value is explicitly specified, the value return is nil (if the body of the method is empty), or the last value used inside the method.

How to return more than one values from inside a method?

def multi_return
  return 'one', 'two', 'three'
end

a, b, c = multi_return

What is a block in Ruby?

In Ruby, a block is an object that contains some Ruby code along with the context necessary to execute it.

Blocks are simply code wrapped in a begin/end construct, but they go further than that. Blocks can be constructed in a number of ways, and in doing so, create an object that holds code that can be passed to methods or held in variables. In Ruby, code block is much like a method without a name tagged on it.

How many ways can we create a block?

  1. begin / end
  2. {}

What does this code do?

myarray = %{one two three four}
myarray.each {|element| print "[" + element + "]..."}

This code output "[one]… [two]… [three]… [four]…". This snippet simply iterates an array using the each method and passes in each element to the code block. The code block can then treat that element as a parameter and operate it much like it would as a method. The code block, in this case, is formed using curly braces. We first call the each method on the myarray object. This each method takes a block as a parameter. We could also write this code using the do/end construct as:

myarray.each do |element|
  print "[" + element + "].... "
end

Can a block return value?

Yes.

Can a block accept multiple parameters?

I do not know. Need research.

What is a Proc?

Think of Proc objects as blocks that are pushed into variables. Proc objects are simply instances of the Proc class that hold a block of code that is executable.

myproc = Proc.new {|animal| puts "I love #{animal}!"}
myproc.call("pandas")

How to make a method that returns a Proc?

def make_show_name(show)
  Proc.new {|host| show + " with " + host}
end

show1 = make_show_name("Practical Cannibalism")
show2 = make_show_name("Cotillions in the Amazon");

show1.call("H. Annabellector")
show2.call("Jack Hannah")

For each invocation, the make_show_name returns a different Proc object. The name of the show is now part of the Proc object created.

We fed make_show_name the name of the show, but we never mentioned it after that. When the show parameter for the make_show_name method is out of scope (the method exited), it should have been destroyed. But this is the beauty of a Proc object. It preserves the context in which it was created and can access that context at any time.

What is the beauty of a Proc object?

It preserves the context in which it was created and can access that context at any time. See above.

**What is the purpose of the lambda method?

Another way to create a Proc object is to bind a block of code using the lambda method. Calling this method is essentially equivalent to calling Proc.new.

myproc = lambda {|x| puts "Arguments: #{x}"}
myproc.call("Texas")

The lambda function will take a block of code and bind it to a Proc, just like Proc.new.

What is the difference between using the lambda function and using Proc.new to create a Proc object?

lproc = lambda {|a,b| puts "#{a + b} <- the sum"}
nproc = lambda {|a,b| puts "#{a + b} <- the sum"}

The nproc.call(1,2,3) returns 3. The lproc.call(1,2,3) results in a "!ArgumentError (wrong number of arguments (3 for 2)". The Proc object created with Proc.new functioned fine when given too many arguments, but the Proc object created by the lambda function is more strict

What is another difference between the lambda function and Proc.new?

Objects created with lambda don't affect the flow of the application outside the block when returning a value. The Proc objects created with Proc.new, on the other hand, will exit their enclosing method when returning.

def procnew
  new_proc = Proc.new { return "I got here..." }
  new_proc.call
  return "...but not here."
end

def lambdaproc
  new_proc = lambda { return "You get here..." }
  new_proc.call
  return "And I got here!"
end

The "puts lambdaproc" results in "And I got here!". The "puts procnew" results in "I got here…"

What must we consider when we need to pass a Proc object as a parameter to another method?

You can pass a Proc object as a parameter just like you would any other object. However there is a performance hit. Fortunately, Ruby gives you a few ways you can put blocks to work with minimal fuss and performance degradation. Outside of taking a Proc parameter, Ruby offers other way to use blocks as parameters.

Example of using implicit block:

def yieldme
  print "1. Enter method. "
  yield
  print "3. Exit method."
end

yieldme { print "2. Enter block.  "}

Notice that the yieldme is invoked with a block. This block is not treated as a parameter of the yieldme method. First, we enter the method and print out our first statement. Second, the yield method is called, and our block is executed. The thread yields control over to the block temporarily. When the block exits, the control is restored to the yieldme method, and the rest of the method is executed.

Another example of using implicit block:

def myeach(myarray)
  iter = 0;
  while (iter < myarray.length):
    yield(myarray[iter])
    iter += 1
  end
end

testarray = [1,2,3,4,5]
myeach(testarray) {|item| print "#{item}:"}

As you can see, the myeach method is invoked with the myarray as the parameter. The block that is part of the myeach invocation is not the body of the myeach method, and it is not a parameter of the myeach method neither. However, this block is invoked whenever the yield statement is invoked inside the myeach method. Notice that the yield method can be invoked with a parameter, and this is passed onto the block.

What happen if you prepend an ampersand to the last parameter of a method?

If we prepend the name of the last parameter of a method with an ampersand, the block that is passed to the method will become a Proc just as if you pass it as a parameter normally. Well, not completely normally. It does a few tricks.

def ampersand(&block)
  block.call
  yield
end
ampersand { print "I'm gettin called! " }

What is "duck typing"?

It is another name for "dynamic typing".

How can we determine the class of an object?

puts File.class
puts File.superclass

File is a class. In Ruby, every class is an object, which is an instance of the Class class which is in turn derived from the Object. The super class of a class is the class which it is derived from. In Ruby, we can say that classes can "inherit" from another class all of its methods and variables.

How to define a class?

To define a class, you place the 'class' keyword at the beginning of a line, followed by a < and the class it inherits from (if it inherit from a class).

class MyFirstClass < Object
end

If we define a class with no inheritance, Ruby assume that you wish to inherit from Object.

What is the purpose of the initialize method defined inside a class?

This is the constructor method. Ruby calls this method when you call (class name).new. When you call the new method, a new object is created, and the initialize (with parameters passed from new) is called to setup the object's state (variables, flags, etc)

class Boogeyman
  def initialize(name, location)
    @name = name
    @location = location
  end
end
monster1 = Boogeyman.new("Mister Creepy", "New Yor, NY")

This initialize method sets some instance variables (variables that are used within an object to retain its state). To set an instance variable, prefix it an at symbol (@). Unlike other languages, you don't have to include these variables inside the class definition.

class Boogeyman
  def change_location(newlocation)
    @location = newlocation
    puts "I moved to #{newlocation}!"
    self.get_info
  end
  def change_name(newname)
    @name = newname
    puts "I shall be called #{newname} from now on!"
    self.get_info
  end
  def get_info
    puts "I am #{@name} in #{@location}."
  end
end
monster1 = Boogeyman.new("Loopy Lou", "Albuquerque, NM")

Notice that in this class we did not define the initialize method. In Ruby, classes are never closed. We can always add methods to or redefine (override) any method for a class simply by opening a class definition and adding or redefining a method. This can be dangerous at times, but overall it's one of the most useful aspect of Ruby's object implementation.

Does Ruby allow us to redefine built-in methods?

Yes. It is possible to override a class's methods (even built-in classes). It can be dangerous. Modifying some of Object's methods or modifying certain operators can make everything go nuts, but at the same time, it can be useful. Rails make extensive use of this concept, especially in its ActiveSupport package.

Unless you know what you are doing, it is best that we do not modify objects that we do not own.

What is the purpose of the self keyword?

The self object always points to the current instance.

What happens if we invoke a method without using the self keyword?

The self keyword is not required in most cases.

When do we need to specify the self keyword?

We have implemented a method named puts in our class, and we want to call it instead of the built-in method.

If we want to add methods to an existing class, do we have to edit the source code of that class?

No. We can always add methods to or redefine (override) any method for a class simply redefining the class:

class Boogeyman
  def change_location(newlocation)
    @location = newlocation
    puts "I moved to #{newlocation}!"
    self.get_info
  end
  def change_name(newname)
    @name = newname
    puts "I shall be called #{newname} from now on!"
    self.get_info
  end
  def get_info
    puts "I am #{@name} in #{@location}."
  end
end
monster1 = Boogeyman.new("Loopy Lou", "Albuquerque, NM")

Notice that we did not redefine the initialize method but it still exist from the original class definition.

What is the difference between instance variable and attributes?

While instance variables are useful, they are not visible to the outside world. But after a while, you might just want to retrieve or change a value within an object.

class Boogeyman
  def scare_factor
    @scare_factor
  end
  def hiding_place
    @hiding_place
  end
  def scare_factor=(factor)
    @scare_factor = factor
  end
  def hiding_place=(place)
    @hiding_place = place
  end
end
monster1 = Boogeyman.new("Crazy Cal", "Nashville, TN")
monster1.scare_factor = 6000

Attributes are simply methods that are used to retrieve or set instance variables. To create a readable attribute, simply create a method and place the instance variable to return its value. To create a writable attribute (a setter method), you simply append an equal sign (=) after the name of the attribute method.

What is the purpose of attr_reader and attr_writer?

In C++ or something similar, all we have to is put the "public" keyword before the variable in the class and it's visible to the outside world. Instead of explicitly defining getter and setter attribute methods as we did previously, we can use attr_reader and attr_writer:

class Boogeyman
  attr_reader :scare_factor, :hiding_place
  attr_writer :scare_factor, :hiding_place
end

to define getter and setter methods. This technique is easier than defining explicitly defining methods, but we lose the flexibility we may gain by making your readers and writers explicit methods.

How can we make a protected method?

A protected method is a method that is accessible by any instance of the class or its derived class. By placing protected on a line and then entering subsequent methods which will be protected:

class Boogeyman
  protected
  def are_you_a_monster?(whoisasking)
    put "Yes, #{whoisasking}, I am a monster!"
    return true
  end
end

What is the difference between protected and private methods?

A protected method allows any instance of the same class or derived class to have access. A private method is only allow the current instance to have access.

How to define a private method?

By placing private on a line and then entering subsequent methods which will be private:

class Boogeyman
  private
  def phone_home(message)
    puts message
  end
  public
  def scare(who)
    phone_home("I just scare the living poop out of #{who}!"
  end
end

How to declare a class constant?

To declare a class constant, simply place the constant name and value into the class definition:

class Boogeyman
  MY_BOSS = 'Mr. Boogeyman'
end

Now every method in class Boogeyman (both instance and class scoped) has access to the value of MY_BOSS.

What is a class variable?

A class variable is like static variable in other languages.

How to declare a class variable?

To create class variables, place two at symbols (@@) before the name of a variable. They operate nearly identical to instance variables except their state lives in the class rather than a particular object.

How can we access class variables?

Boogeyman asked us that we have a way to get the name of the newest denizen he has released and where he is. We can provide this with a class variable:

class Boogeyman
  # We will redefine initialize
  def initialize(name, location)
    @name = name
    @location = location

    @@latest = @name
    @@location = @location

    puts "Yes, master?"
  end
end

puts Boogeyman.latest

We can access a class variable by using the class name, followed by a dot, and the variable name. You can access a class variable from either class scoped or instance scoped methods. Notice that because @@location, @location, and location are all scoped different, they can all use the same name.

What is a class method?

Class methods are methods that can be invoked by using the class name without having to create an instance of the class.

How to define a class method?

To define a class method, prefix the method name with the class name, followed by a dot:

class Boogeyman
  def Boogeyman.latest_monster
    puts "The latest monster is #{@@latest}."
    puts "His location is #{@@location}."
  end
end

Boogeyman.latest_monster

Class methods only have access to class variables. Unlike class variables, class methods must be access by using its full name.

Inside an instance method, can we access class variable by its short name?

Yes.

Inside an instance method, can we access class method by its short name?

No. We must access the class method using its full name (like Boogeyman.latest_monster instead of just latest_monster).

How to create a module?

Modules are namespaces?

The syntax for creating a module is very similar to the syntax for creating a class. You place the keyword module followed by the module name. Then, on subsequent lines, you enter the methods and classes which should reside in this method followed by the 'end' keyword:

module FighterValues
  BAMBOO_HEAD = { 'life' => 120, 'hit' => 9}
  DEATH =  {'life' => 90, 'hit' => 13}
  KOALA = {'life' => 100, 'hit' => 10}
  CHUCK_NORRIS = {'life' => 6000, 'hit' => 999999999}

  def chuck_fact
    puts "Chuck Norris' tear can cure cancer..."
    puts "Too bad he never cries."
  end
end

module ConstantValues
  DEATH = -5
  EASY_HANDICAP = 10
  MEDIUM_HANDICAP = 25
  HARD_HANDICAP = 50
end

puts FighterValues::DEATH
puts ConstantValues::DEATH

How can we access a constant inside a module?

Use double colons:

puts FighterValues::DEATH
puts ConstantValues::DEATH

What is mixin?

Code that is "mixed into" a class as if it is part of its original code. A class in Ruby can only inherit from one class (though it can have a chain of inheritance). Mixins eliminate the need for that. You can create a class, inherit from another class, and mix in as many modules as you need. This feature is especially great if the code that you need to mixin needs to only be mixed in (it won't ever be used by itself):

module Movement
  def run
    puts "I'm running!"
  end
  def walk
    put "I'm walking a bit briskly!"
  end

  def crawl
    puts "I'm so slowwww!"
  end
end

class Man
  include Movement

  def jump
    puts "I'm bipedal and I can jump like a fool!"
  end
end

Class Sloth
  include Movement
  def flop
    puts "It's all a lie...all I can do is flop around."
  end
end

mister_man = Man.new
mister_man.run

mister_slothy = Sloth.new
mister_slothy.flop

As you can see, this mechanism is very similar to inheritance in that you can use all of the mixin's code. To use a mixin, simply define a module and then use the include keyword followed by the module's name. From then on, the class has access to all of that module's constants and methods.

This example does not do this mechanism justice. It doesn't demonstrate the usage of module constants in a mixin. It doesn't do much with the host class. It is merely an introductory example in hopes that you will experiment and read further. The magic really happens when the class actually interacts with the mixin.

What cautions should we be aware of when developing or using mixins?

Mixins are awesome as long as they are well written, but if the developer doesn't pay attention and be careful about naming they can create havoc in your application. For example, let's say you have a constant called PI which holds Pi to the 72nd digit, but you mix in a trigonometry library which has a constant named PI which is only Pi to the 5th digit, the mixed in library's constant will override your constant. It is best to be sure that your naming scheme is unique so as to not stomp on other's code.

When you call a method, Ruby will first look to the host class (the class being mixed into), and then to its mixins, and then to its super class, and its mixins, and so on. This behavior is the exact opposite of constants. This could be a blessing or a curse.

What are the two mechanisms to include a files in Ruby?

load and require.

What are the differences between load and require?

The load keyword includes a source code file unconditionally while 'require' will only include it once (which means no duplication of variables and methods).

load "libraries/myfile.rb"
require "/home/myaccount/code/libraries/myotherfile.rb"

Both keywords accepts either a relative path or absolute path. If Ruby identifies it as a relative path, it will search for the file in the current path (stored in $:). The require statement is also great in that you can use it in conditionals, loops, and other constructs or use variables in its paths.

Local variables in included files do not trickle into the context they are included in. This is contrary to PHP's and C/C++'s behavior. These variables are locked into the context that they are written in.

Does Ruby has public, private, and protected keywords?

Yes and no. These keywords are only used to declare access privileges for methods. These keywords are not used on instance variables. Instance variables are always private. To access instance variables we must explicitly define our getter / setter methods or use the attr_reader and attr_writer keywords to implicitly define our getter / setter methods.

Example of if statement:

if not (true != false) && (true != true):
    puts "Whoa! Alternative dimension"
elsif (false === 'false') then
    puts "Type conversion?  I think not..."
elsif (true ==1) or (3 == false)
    puts "Booleans != Numbers"
else
    puts "I gues we're still OK!"
end

An if statement is constructed by placing the if keyword on a line followed by a conditional comparing values equality, inequality, etc. The if statement itself opens the conditional block (if is the initiator of a begin/end block). You can create an if block simply with the if statement, its block of code, and the end keyword.

Refer to http://www.humblelittlerubybook.com/book/html/chapter3.html for a list of conditional operators.

Example of the case statement:

In Ruby, the case statement has two forms.

the_tao = 1234
case the_tao
when 666:
    puts "That's such a lie!"
when 1337
    puts "Liarrrr!"
when 32767 then
    puts "Whatevurrrr!
else
    puts "You are harmonized with the Tao."
end

This form of case statement simply test the target value against the values in the cases. The cases are form using the when keyword followed by the test which followed either by the word 'then' or a colon (both of which are non-essential if the case starts on the next line). The when keyword segments the cases so no "end" keyword is needed except to close the case block.

The second form of the case statement add more flexibility by allowing us to use conditionals like the if statements:

enlightenment = 42
case
when enlightenment > 60:
    puts "You are too hasty, grasshopper."
when enlightenment < 40 or enlightenment == nil:
    puts "You are like the sloth, my friend.  Diligence is the key!"
when enlightenment == 42:
    puts "Hello, Enlightened One."
else
    puts "Yeah, not quite, pal.  Maybe next time."
end

A commonality between the two forms is their lack of "fall through". In many programming languages, the case block requires some sort of keyword (usually break or something similar) which tells the application to stop checking the other conditionals.

If the break keyword is present inside a case block, it will exit the switch block if it is encountered. You many need to use the break statement inside an if statement in circumstances that you want to exit the case statement early without executing the remaining statements.

Example of using while loop:

x = 0
while (x < 10):
    print x.to_s # print is like puts without a \n at the end
    x += 1
end

Does Ruby have a for loop in traditional sense?

No. Ruby does not offers a "for loop" in the traditional sense. It does however offer one that uses the keyword 'for'.

What is the purpose of the for loop in Ruby?

The "for loop" in Ruby behaves very similarly (almost identically) to the for loop in Python. A collection is provided, and the for loop provides a local variable to hold each item as it iterates.

my_events = [2,4,6,8,10,12,14]
for my_int in my_events
    print my_int.to_s + ", "
end

This is like saying "I want to create a local variable my_int for each object in my_events and do something with it." Each time the loop iterates, the next value in my_events is copied into the variable my_int. This variable allows you to manipulate the item in the collection easily (and, since the original object is copied into that variable, you can manipulate it without risk of bit twiddling in the original collection).

The for loop is really just syntactic sugar for an iterator. An iterator is simply a block of code that iterates over a collection provided by the each method of a class:

my_events = [2,4,6,8,10,12,14]
my_events.each do |my_int|
    print my_int.to_s + ", "
end

How to handle exception?

To handle an exception we must create a rescue block:

def method_of_doom
    my_string = "I sense something doom."
    my_string.non_existent_menthod
rescue Exception => e:
    put "Problem: " + e.to_s
end

Can we use multiple rescue blocks?

Yes.

def method_of_doom
    my_string = "I sense pending doom."
    my_string.non_existent_method
rescue NoMethodError:
    puts "You're missing that method, fool!"
rescue Exception:
    puts "Uhh...there's a problem with that method."
end

What is the meaning of the else clause that is part of a rescue block?

The else clause will execute if there are not exception raised:

def no_problemo
    x = 0
    x += 19
rescue Exception
    puts "Oh noes!"
else
    puts "All clear!"
end

The else clause may be useful if we want to report that an exception did not happen, but it is not definitive (when an exception happened, the else clause is not executed).

What is the purpose of the ensure clause that is part of a rescue block?

This clause holds code that is always executed (regardless if an exception happened or not):

def dance_a_jiq
    "I'm a dancin'!"
    "Do so do!"
    rebel_yell = "yee haw!".upcase!
rescue Exception
    print "I fell down, dang it!"
else
    print rebel_yell
ensure
    print "That's all folks!"
end

Can rescue blocks be used as statement modifier?

Yes.

obj.non_existent_method rescue puts "Crash!"

However, you cannot specify what sort of exception to handle. That is better left to the formal rescue block.

A statement modifier is just something that you append to a statement at the end. When we use the while or until as a statement modifier, the statement is repeated executed until the condition of the while / until clause is satisfied. In this case, the statement is executed, and if an exception occurred, the rescue block is executed.

Can the rescue block return a value?

Yes.

my_value = obj.non_existent_method rescue "Burn!"
puts my_value

-> Burn!

What is the purpose of the retry statement?

Retry the statement:

def make_request
    if (@http11)
        self.send('HTTP/1.1')
    else
        self.send('HTTP/1.0')
    end
rescue ProtocolError
    @http11 = false
    retry
end

Be careful with this though. It can cause serious problems if the problem is never fixed, the same block of code is looped over again and again because your application is retrying it.

How to raise your own exception?

The raise keyword, and the fail keyword can be called a number of ways:

raise "You specified something wonky!"
raise
raise NoMethodError, "That method doesn't exist here!", caller

The first form provide a message for the RuntimeError. The second form will re-raise the current exception so it can be passed further up the call stack or raise a RuntimeError (with no message) if there is no exception (use it inside your own if statement). The last form allows you to specify an exception type, a message, and a stack trace object (which is usually just caller, a reference to the Kernel.caller method). Good software practice says that you should be as specific as possible with your exception. Instead of just throwing the RuntimeErrors all the time, try to throw a more specific exception type.

How to create your own exception type?

class GenderError < RuntimeError
    attr :what_they_put

    def initialize(their_input)
        @what_they_put = their_input
    end
end

To create our own exception type, simply derive from any of the exception classes.

class Person
    def define_gender(gender)
        if (gender.upcase != 'FEMALE') && (gender.upcase != 'MALE')
            raise GenderError.new(gender), "Invalid input!"
        end
    end

    def initialize(gender)
        self.define_gender(gender)
    rescue GenderError => bad
        puts "You gave me some bad input: " + bad.what_they_put
        raise
    end
end

my_guy = Person.new("Who knows?")
-> You gave me some bad input: Who knows?
-> ! GenderError ("Invalid input!")

Notice that our exception class, GenderError just like a normal class, can take parameters from the 'new' method.

Because we re-raise the error in our rescue block, the exception bubble up the stack and kill the program.

When we are implementing our own exception class, can we add more information our exception class?

Exceptions are objects, and thus have classes behind them. When we create our own exception class, we can add methods and attributes to it to hold value of the user's input. This is useful if we wish to provide more information to the exception handlers or if we would like to provide help in recovering from exceptions by providing methods in the exception.

If rescue and raise equivalent to try/catch and throw in other language, what are throw and catch in Ruby?

In Ruby, a 'catch' block is given an identifier as an argument. You can "throw" this identifier in the ensuing code. Ruby will then look up the stack to see where the matching catch is, and if it's found, Ruby will break normal processing and exit the 'catch' block.

princess = DamselInDistress.new

catch :hes_a_failure do
    # YAY! Someone's here to save her...
    print "My prince is here!"
    # OH NO!  The villain has eaten his liver! He dies!
    princess.is_saved = false

    if (princess.is_saved == true)
        puts "Hooray!"
    else
        puts "Poo! Not again!"
        throw :hes_a_failure
    end

    puts "I'm going to sleep until the next guy..."
    #Nap
end

A catch block is started by placing the catch keyword, and identifier, then the do keyword on a line. The identifier is used with the throw keyword and can either be a symbol or a string. The code is run until a matching throw statement (i.e. the throw's identifier matches the catch's identifier) is encountered (if one is encountered) in which case the catch block exits without executing any code after the throw statement. In this example, you can see that "My prince is here!" and "Poo! Not again!" are output but "I'm going to sleep until the next guy…" is not. The block exited after the matching throw statement (i.e. throw :hes_a_failure) was found. This construct is useful if you need to simply exit the code block if an error occurs or if your code is buried in deeply nested loops and you want to break out of them quickly / easily.

Compared to Java, rescue is like the throws clause that indicates which exceptions your method will throw. The rescue blocks are part of the method definition. They provide exception handling for the method, at the method level. They can even return values. Inside a Java catch block, we can set value for a variable, and outside the catch block, we can return the value inside that variable. I never put the return statement inside a Java catch block, and see what problem it may cause. In Java, I think putting the return statement inside a catch block is not a wise idea (I rather letter the try/catch block finish its thing rather than returning early inside the catch block). In Ruby's rescue block, on the other hand, putting the return statement inside the rescue block seems to be the only way to return value when an exception happens.

The 'raise' statement in Ruby is like the 'throw' statement in Java.

The 'catch' statement in Ruby is not like the 'catch' keyword in Java. The 'catch' statement in Ruby is more or less like the 'try' statement in Java, but not exactly. The catch statement in Ruby takes a block of code, run it, and see if an exception is thrown (using the throw keyword instead of the raise keyword).

With Java's try statement, we can have multiple catch clause. With Ruby's catch statement, I think we can only have one identifier associated with the catch statement.

Need to read more on this catch statement. Is it a loop?

How can we do exception handling in the main Ruby program?

We've seen the rescue blocks at the method level. We've seen the catch statement which can be used anywhere in the code, but it seems a bit limited. How can we handle exception in the main program like a "global exception handler" in PHP?

Working with Files:

File.directory?("textfile.txt")
File.file?("textfile.txt")
File.exists?("textfile.txt")
File.size?("textfile.txt")
File.extname("textfile.txt")
File.executable?("textfile.txt")
File.executable_real?("textfile.txt")
File.readable?("textfile.txt")
File.readable_real?("textfile.txt")
File.writable?("textfile.txt")
File.writable_real?("textfile.txt")
File.owned?("textfile.txt")
File.grpowned?("textfile.txt")
File.setgid?("textfile.txt")
File.setuid?("textfile.txt")
File.delete("textfile.txt")
File.rename("textfile.txt", "textfile.txt.bak")
File.chown(nil, 201, "textfile.txt")
File.chmod(0777, "textfile.txt")

See http://www.humblelittlerubybook.com/book/html/chapter4.html for a list of File Access Modes.

How do executable_real?, readable_real?, and writable_real? differ from executable, readable, writable?

The executable?, readable?, and writable? methods have companion methods called executable_real?, readable_real?, and writable_real? which make sure that the owner of the process has that ability with that file. Of course, if you own the file, it probably doesn't matter. You can find out if you own it using the 'owned?' method, which will return true if the process owner indeed owns the specified file.

What will File.size? return when the file size is zero?

It will return nil.

How to process a file one line at a time?

myfile = File.open("textfile.txt", "r")
myfile.each_line {|line| puts line }
myfile.close

You can optionally feed each_line a parameter that will act as the line ending in place of "\n".

You can also avoid calling myfile.close by using a block:

File.open("textfile.txt") do |myfile|
    myfile.each_line {|line| puts line}
end

Or you can:

IO.foreach("textfile.txt") {|line| puts line}

How to write to a file?

File.open("textfile.txt","w") do |myfile|
    myfile.write("Howdy!")
end

or more like IOStream in C++:

File.open("textfile.txt", "w") do |myfile|
    myfile << "Howdy!\n" << "There are " << count << " pandas!"
end

How to use Threads?

Using threads in Ruby is simple. Just pass a block of code to the Thread class's constructor.

first = Thread.new() do
    myindex = 0
    while (myindex < 10):
        puts "Thread One!"
        sleep 3
        myindex += 1
    end
end

second = Thread.new() do
    myindex2 = 0
    while(myindex2 < 5):
        puts "Thread Two!"
        sleep 5
        myindex2 += 1
    end
end

third = Thread.new() do
    myindex3 = 0
    while (myindex3 < 2):
        puts "Thread Three!"
        sleep 10
        myindex3 += 1
    end
end

first.join()
second.join()
third.join()

The threads will run by themselves and be killed when your program ends. Calling the join method cause your program to wait until all threads that have been joined exit.

What if you do not want you main program to wait until the thread finish but do want to give it a bit of time?

You can specify a timeout with the join method:

first.join(15)

What is the purpose of the pass keyword?

It tells the thread scheduler to pass the execution to another thread. This is like 'yield' in other language.

What is the purpose of the stop keyword inside a thread?

It stops the thread's execution which can be started again at a later time. This is useful in situations where a thread needs to pause until you can accomplish another task:

mate = Thread.new do
    puts "Ahoy! Can I be dropping the anchor sir?"
    Thread.stop
    puts "Aye sir, dropping anchor!"
end

Thread.pass

puts "CAPTAIN: Aye, laddy!"
mate.run
mate.join

As you can see, the 'mate' thread is created, it then stop itself and wait until the main program invoke mate.run.

What is the purpose of 'Thread.exit' ?

Use 'Thread.exit' inside a thread to tell it to gracefully exit / terminate itself.

**What is the purpose of 'Thread.kill' **

Use 'Thread.kill' outside a thread to forcefully terminate it:

first = Thread.new do
    while (true):
        do_something
    end
end

Thread.kill(first)

What is the purpose of 'Thread.current' ?

The current method gives you access to the current thread.

What is the purpose of 'Thread.list' ?

The list method list all threads that are runnable or stopped.

What is the purpose of the 'alive?' method?

The 'alive?' method will tell you whether or not the thread is active or not. It will return true if the thread is running or sleeping and false if it has exited or stopped.

What is the purpose of the 'status?' method?

The status method will return:

  • run: if the thread is running as normal
  • sleep: if the thread is sleeping
  • aborting: if the thread is aborting
  • nil: if terminated with an exception
  • false: if the thread terminated normally

What is the purpose of the 'stop?' method?

Testing whether or not a thread is simply running can be done using the 'stop?' method. Ruby returns true if the thread is stopped or sleeping. Otherwise, it returns false.

Can a thread return value?

Yes. You can obtain this value using the 'value' method:

calculator = Thread.new { 12 / 4 * 3 }
calculator.value

This is excellent for long calculations whose value isn't needed right away. Doing them this way lets you run them on another thread so they do not interrupt the main thread and the execution of your program.

How many ways we spawn a process?

Sometimes we need to spawn a new process altogether. Whether you need to execute a third party program or just invoke another Ruby instance that runs your script, spawning external process can be important at times. Ruby offers a few ways to spawn and control new process:

  • The 'system' method
  • The backtick
  • exec / fork
system("cat /etc/passwd")

extern = `whoami`
puts "Your username is #{extern}."

What is the purpose of the '$?' variable?

It stores the exit code of the external program invoked by the 'system' method.

What is the difference between the 'system' method and the backtick?

The 'system' method will vomit the output onto wherever your application's output is being streamed to, which means you can not capture it. The backtick also spawn an application in a subprocess but also allow you to capture its output.

What is the purpose of IO.popen method?

The 'system' method works well enough in a lot of cases, but what if you need to provide some interactivity with the application? Say you need to give it some input or perhaps it gives you delayed output and you'd like to start processing it before it's done executing. Ruby offers the IO.popen method for that purpose. The popen method will spawn an application and then give you a stream which you can read from and write to just like any other stream.

rb = IO.popen("ruby", "w+")
rb.puts "Whoa! Radical subprocess, dude!"
rb.close_write

puts rb.gets

How to spawn a process using exec / fork?

exec("apachectl restart") if fork.nil?

Process.wait

This has the same basic effect as using system, except that you can tell your application to wait until that process is done using Process.wait. This is a good idea if you are running a subprocess that would cause damage if exited prematurely.

How to access environment variables?

ENV['SHELL']
ENV['HOME']
ENV['USER']
ENV['USERNAME']

How to pass environment variables to sub-process?

ENV['USERNAME'] = 'dont_do_this'

You can pass environment variables to sub-processes, but avoid overwriting environment variables that are pre-defined by the targeted operating systems.

How to access command line parameters?

ARGV.each {|arg| puts "Arg: #{arg}" }

What is the purpose of 'ruby -e' ?

Use this command:

ruby -e "puts $:"

to determine the paths that Ruby will look for libraries.

How to determine information about our Ruby installation?

You can gather some information about how Ruby was built and in what environment. This information can be useful if a bug exists for a specific build environment, and you want to see if a problem you are experiencing might be a result of that bug. This information is located in the Config module in the file rbconfig.rb in the library directory, usually in a directory under which is labeled by the build environment (i.e. i386-mswin32). You can access this information programmatically:

include Config
puts CONFIG['host_os']
puts CONFIG['target_os']
puts CONFIG['libdir']
puts CONFIG['build_cpu']

How to read values from a Windows ini file?

require 'Win32API'

getvalue = Win32API.new('kernel32', 'GetPrivateProfileString', %w(P P P P L P), 'L')
strlen = Win32API.new('kernel32', 'lstrlenA', %w(P), 'L');

retstr = ' ' * (255 + 1)
getvalue.Call('database', 'login', '', retstr, 255, 'C:/test.ini')

length = strlen.Call(retstr)
puts retstr[0..length - 1]

First, create instances of the Win32API class for each Win32 function that we are going to call. The first parameter is the API module to look in (GetPrivateProfileString lives in kernel32). The second parameter is the function name that we wish to use. The third parameter is an array of parameter types that the function takes (P for string pointer, N and L for numbers, I for integers, V for void). The fourth parameter is the return type (we specified L for long number.

How to read values from the Registry?

The Win32 module provides you with a very friendly interface to operate on the Window registry. To operate on the registry, you need to first call open on the Win32::Registry class and give it a registry path to open, followed by a block:

require 'win32/registry'

Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\WindowsNT\CurrentVersion\') do |reg|
    # Do some work
    value = reg['ProductName']
    value = reg['PathName', Win32::Registry::REG_SZ]
    type, value = reg.read('BuildLab')
end

The second call will return the value, but will throw an error if the value returned does not match the type given as the second parameter. If the value for PathName were DWORD in the registry but you requested a REG_SZ, it would have thrown a TypeError.

See http://www.humblelittlerubybook.com/book/html/chapter4.html for a list of registry type constants.

The third call uses the read method. The advantage of calling the value this way is that it gives you the type of the key. This is useful if we are iterating over a set of keys and we need to perform specific operations on keys that are of certain types (or you do not necessarily knows or care to knows about the type of the key).

How can we iterate over values and subkeys?

We can also have the option to enumerate values and subkeys, and in turn walk over the entire collection of values or a series of subkeys doing operations, storing or changing values, etc. We can use the each_value and each_key method to enumerate values or keys:

Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\WindowsNT\CurrentVersion\') do |reg|
    # Do some work
    reg.each_value {|name, type, data| puts name + " = " + data }
    reg.each_key {|key, wtime| puts key + " :: " + wtime}
end

Can a block accept multiple parameters?

Yes

Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\WindowsNT\CurrentVersion\') do |reg|
    # Do some work
    reg.each_value {|name, type, data| puts name + " = " + data }
    reg.each_key {|key, wtime| puts key + " :: " + wtime}
end

How to write values to the registry?

Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\WindowsNT\CurrentVersion\') do |reg|
    # Do some work
    reg['RevisionNumber'] = '1337'
    reg['Name', Win32::Registry::REG_MULTI_SZ] = 'Mr.\0Neighborly\0\0'
    reg.write('MyPath', Win32::Registry::REG_EXPAND_SZ, '%PATH%')
end

The second call allows you to write a value with the specified type. It will throw a TypeError if it's the wrong type.

In the last call, it use the write method. The first parameter is the name of the key. The second parameter is the type. The third paramter is the value to assign to it.

How to delete keys and values from the registry?

Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\Microsoft\WindowsNT\CurrentVersion\') do |reg|
    # Do some work
    reg.delete_value('MyVersion')
    reg.delete_key('FavoriteCheese')
    reg.delete_key('Ex-Wives', true)
end

The first method, delete_value, will delete the value which you specify as the first parameter. The second method, delete_key, will delete the key which you specify, and if the second optional boolean parameter is set to true, it will delete the key recursively.

How to use OLE Automation to launch IE?

require 'win32ole'
myie = WIN32OLE.new('InternetExplorer.Application')
myie.visible = true
myie.navigate("http://www.humblelittlerubybook.com")
myie.left = 0
myie['top'] = 0

How to handle OLE events?

The Win32OLE class can also be used to be notified of what is going on in a application. This is done through an event sink mechanism that is exposed by the application and then consumed by our Ruby application.

require 'win32ole'

# Handler method
def stop_msg_loop
    puts "Application closed."
    throw :appclosed
end

def handler(event, *args)
    puts "Event fired! : #{event}"
end

# Main code
ie = WIN32OLE.new('InternetExplore.Application')
ie.visible = true
ie.gohome
sink = WIN32OLD_EVENT.new(ie, 'DWebBrowserEvents')
sink.on_event {|*args| handler(*args)}
sink.on_event("Quit") {|*args| stop_msg_loop}

catch(:appclosed) {
    loop {
        WIN32OLE_EVENT.message_loop
    }
}

To subscribe to events, you need to follow the general procedure for consuming an OLE interface: import the win32ole library, create a new WIN32OLE instance, call methods and / o attributes. The first new part of this code is the creation of a WIN32OLE_EVENT instance. The constructor of this class is given an WIN32OLE instance and the name of an event sink exposed by this interface (if an event sink does not exist, an error is thrown). You can then look into events using the on_event method, which is given a block as a parameter. This block is then in turn given the event's arguments. You can use on_event in one of two ways. The first is to give it a general handler, as in the first call to on_event. This handler becomes a sort of catch all for any events that don't have explicit handlers. You can also give events explicit handlers, like the second call gives the "Quit" event.

Right now, there is no easy way to detach from an event, so a little hack is to use 'catch' to break out of the message loop seems to be the easiest way to do it.

Does Ruby support working with WMI (Windows Management Instrumentation)?

Yes. WMI can be used for a number of administrative and management tasks, such as service management, process management, event watching, log auditing, and so on. This can be done on both local and remote machines. To get a list of services on the local machine along with their description and status:

require 'win32ole'
wmi = WIN32OLE.connect("winmgmts:\\\\.")
wmi.InstanceOf("Win32_Service").each do |s|
    puts s.Caption + ": " + s.State
    puts s.Description
    puts
end

The connect method does basically the same thing as the new method, except the connect method hooks into an existing instance of an OLE server whereas the new method creates a new instance. In our code, we can use StopService, or StartService.

Does Ruby support WMI events?

Yes. The win32ole library also allows use to subscribe to WMI (Windows Management and Instrumentation) events, which span the whole gamut of system-wide events such as file creation, process creation, service actions, log entries, and so on.

require 'win32ole'
locator = WIN32OLE.new("WbemScripting.SWbemLocator.1")
service = locator.ConnectServer("./","","","")
proc = service.Get "Win32_Process"
rc = proc.Create('notepad.exe', nil, nil, nil)
processid = WIN32OLE::ARGV[3]

puts "New process id: #{processid}"

query = "select * from __InstanceDeletionEvent within 1 where targetinstance isa 'WIN32_Process' and targetinstance.Handle = #{processid}"
event = service.ExecNotificationQuery(query)
event.nextevent
puts "Process terminated."

Because the way that WMI operates, you cannot use the built-in event mechanism in the win32ole library, but it's fairly simple to get this working nontheless. First, create a new instance of the WIN32OLE class using the new method and point it at the server Wbemscripting.SWbemLocator. This OLE server is the basic equivalent of connecting like we did before with winmgts://, but using this in conjunction with the sub-sequent call to ConnectServer allows you to do two things.

First, you can connect to remote computers. Second, you can provide login credentials as the last two parameters to this method. None are needed on the local machine usually (unless you are not an administrator or privileged account), but if this was a remote machine call, you would probably need a user name as the third parameter and the password as the fourth parameter.

Next, we use the WMI method to get a reference to the Win32_Process class and create an instance of it, passing in "notepad.exe" as the process to start. Doing so creates a new Notepad instance and returns some data about it, which we use to get the process ID.

Next, we use WQL (WMI Query Language) to tell WMI that we're going to be watching for processes to be destroyed that have the process ID of the process that we created. The WQL statement is executed using the ExecNotificationQuery method that is exposed by WMI. This method returns an event notifier object, which we can call the nextevent method on. This method tells the current thread to pause until the next event is fired, so if we were to use this in an actual application that should continue running, this should be forked into its own thread

How to use TCPServer to create a network server?

require "socket"
server = TCPServer.new('localhost', 0)
sockaddr = server.addr
puts "Echo server running on #{sockaddr.join(':')}"

while true
    Thread.start(server.accept) do |sock|
        puts "#{sock} connected at #{Time.now}"
        while sock.gets
            sock.write($_)
            puts "User entered: #{$_}"
        end
        puts "#{sock} disconnected at #{Time.now}"
        sock.close
    end
end

First, we must include the socket module, which will give you access to TCPServer and all its related modules and classes. Next, you must create a TCPServer instance using either the new method or its synonym, the open method. The first parameter is the interface to bind to. If this is left blank, then Ruby binds to all available interfaces on the host. The second parameter is the port number. If this is 0, the system automatically selects an available port.

Upon entering the loop, we tell the application to wait until a new socket is connected (which fires server.accept). When the socket connect, a new Thread object is created and the enclosed block is executed.

How to use TCPSocket to implement a TCP client?

require "socket"
clientsocket = TCPSocket.open("www.somewebsite.com",80)
clientsocket.write("Cookie: xxx")
clientsocket.write("\n")

# read from the socket
while (lines = clientsocket.gets)
    print lines
end
clientsocket.close

First, we need to import the socket library. Next, we open a TCPSocket. The first parameter is the hostname or network address to connect to. The second parameter is the port number to connect on. Now, we have a socket, we can treat it just like a stream that we get from a file or something similar. Therefore, we can use gets to obtain data from it. We can also use 'read', 'readline', 'write', 'writeline', and any other stream reading / writing command.

Socket also have their own method such as 'recv' to receive data from the socket, and send to send data over the socket.

How to make an HTTP GET request?

require 'net/http'
Net::HTTP.get_print 'www.digg.com', '/rss/index.xml'
require 'net/http'
require 'uri'
Net::HTTP.get_print URI.parse('http://www.ruby-lang.org')

How to make an HTTP POST request?

require 'net/http'
require 'uri'
postit = Net::HTTP.post_form(URI.parse('http://zip4.usps.com/zip4/zcl_3_results.jsp'), {'zip5' => '37998'})
puts postit.body

The above snippet will use USPS ZIP code lookup to find out the city corresponding to that zip code. Using the post_form method, we can post a form by providing the form keys and values in a hash as the second parameter.

If we are behind a web proxy which requires a username and password, how can we access the web with Ruby?

require 'net/http'
require 'uri'

content = Net::HTTP::Proxy('myproxyhost', 8080, 'username', 'password').get(URI.parse('http://www.cnn.com/'))

How to FTP with Ruby?

require 'net/ftp'
ftp = Net::FTP.new('ftp.gnu.org')
ftp.login('anonymous', 'me@somewhere.com')
ftp.chdir('gnu/readline/')
files = ftp.list('r*')
puts files
ftp.getbinaryfile('readline-5.1.tar.gz', 'rline.tar.gz')
ftp.close

If we are logging in anonymously, it's not completely necessary to provide a username and password. If left blank, Ruby will substitute 'anonymous' as the username, and 'anonymous@yourhostname' as the password. Next, we need to navigate to the proper directory. Here we use the chdir method to change directories to the gnu/readline/ folder and the list method to get a list of the files in that directory. We can use the gettextfile or getbinaryfile methods to get files or puttextfile or putbinaryfile to upload local files to the server. The get methods require two parameters (the remote file to get and the local filename to copy to). The put methods also require two parameters (the local file to copy, and the remote filename to copy to).

How to use send email using Ruby?

requite 'net/smtp'
message = <<MESSAGE
From: Your Name <you@you.com>
To: That Guy <him@him.com>
Subject: My fine hat is misplaced
Date: Sat, 15 Sep 2006 16:26:43 +0900
Message-Id: <thisisunique@you.com>

Where is my fedora?
MESSAGE

smtp = Net::SMTP.start('me.com', 25)
smtp.send_message msgstr, 'you@you.com', 'him@him.com', 'you.com'
smtp.finish

The Net::SMTP.start method takes two parameters (the hostname or IP address and the port number of your SMTP server). Next, call the send_message method, giving it the message, the sender's email address, the recipient's email address, and 'HELO domain' as parameter. The 'HELO domain' is used by some email servers and spam filters to make sure that the e-mail is legitimate. Finally, call the finish method to end the SMTP session. If your SMTP server requires authentication, you need to make the start method call like the following:

Net::SMTP.start('me.com', 25, 'you.com', 'you', 'mypw', :plain)

The last parameter indicates which authentication scheme should be used. Here we use :plain. Other authentication schemes are login, cram_md5.

How to download mail from a POP?

require 'net/pop'

pop = Net::POP3.new('mymailserver.com')
pop.start('myaccount','mypwd')
if pop.mails.empty?
    puts 'No mail to grab'
else
    pop.each_mail do |msg|
        puts msg.pop
        # msg.delete
    end
end
pop.finish

How to download mail from an IMAP server?

require 'net/imap'
imap = Net::IMAP.new('mail.example.com')
imap.authenticate('LOGIN', 'joe', 'password')
imap.examine('INBOX')
imap.search(["RECENT"]).each do |msg_id|
    envelop = imap.fetch(msg_id, "ENVELOPE")[0].attr["ENVELOPE"]
    puts "#{envelope.from[0].name}: \t#{envelope.subject}"
end

The two authentication schemes supported by IMAP are LOGIN, and CRAM-MD5. The examine method gives you read-only access to a mailbox or folder. The select method, which is used in the same way, allows editing access. You can use the search method to grab information, or use methods like copy and store.

How to make XML-RPC call?

require 'xmlrpc/client'
server = XMLRPC::Client.new2("http://xmlrpc-c.sourceforge.net/api/sample.php")
result = server.call("sample.sumAndDifference", 5, 3)
puts "#{result['difference']} and #{result['sum']}"

-> 2 and 8

First, you need to include the library and create a new instance using the new2 method (or the new with a lot of parameters or new3 with a hash of every parameter needed). Then use the call method to make an XML-RPC call to the server. The call method takes the remote method as the first parameter and the method's parameters as the remaining parameters. The results are then returned to you as a usable hash (i.e. result['difference'])

How to make a SOAP call?

text = 'Here I lie in a sweater poorly knit.'
lang = 'en_de'

require 'soap/rpc/driver'
server = 'http://services.xmethods.net/perl/soaplite.cgi'
InterfaceNS = 'urn:xmethodsBabelFish'
wireDumpDev = nil
drv = SOAP::RPC::Driver.new(server, InterfaceNS)
drv.wiredump_dev = wireDumpDev
drv.add_method_with_soapaction('BabelFish', InterfaceNS + "#BabelFish", 'translationmode', 'sourcedata')
puts drv.BabelFish(lang, text)

The InterfaceNS is the namespace that the method you wish to call is located in. The last one is the "dump" handler for errors. If it is set to nil, it becomes the standard error channel. Next, a new SOAP::RPC::Driver is created that points to the service and namespace specified earlier and is told dump to stderr. The next little bit of code demonstrates an interesting feature of soap4r, which is probably what sets it apart from most other SOAP wrappers. The add_method_with_soapaction uses Ruby's dynamic nature to add a method to the Driver object. This means that rather than marshalling and calling and doing a lot of stuff, we can now call the method on the Driver object like any other method

What is DRb?

The DRb (Distributed Ruby) package provides a simple way to handle distributed computing in Ruby.

Every DRb application has two components: a server and clients. The server will start a TCP server, which will expose objects, accept connections, and respond to actions requested over those connections. Clients will establish connections to DRb server, bind to objects, and send messages to those objects similar to messages that are sent to local objects when calling methods and attributes.

Setting up a DRb server:

class FSWatcherService
    def initialize(filename)
        @file = filename
    end
    def getspace
        return File.size(@file)
    end
end

#Now that we have a class to work with, we need to wrap it in a DRb server.
#This is done by simply calling the start_service method from the drb module
#and giving it a few parameters

require 'drb/drb'
require 'thread'
class SizeService
    def initialize(filename)
        @file = filename
    end
    def getspace
        return File.size(@file)
    end
end

DRb.start_service("druby://:9876", SizeService.new('cats.log'))
puts DRb.uri
DRb.thread.join

First you need to include both the DRb module (drb/drb) and the thread module so you can join the DRb server's thread into the main one. Next, you see the class that we made earlier. Then you need to call the start_service method from the DRb class. This will start the DRb server on the specified URI and expose the indicated object. The DRb URI is then printed to the console. The DRb server's thread is then joined to the main thread, an the server idles until connected.

The DRb client:

The basic process is that you call start_service, bind to the remote object, and then use it just like a remote object:

require 'drb/drb'
Drb.start_service
remoteobj = DRbObject.new(nil, 'druby://domo:9876')
puts "Log file usage is #{remoteobj.getspace()} bytes."

How to implement database driven application?

require 'dbi'
DBI.connect('DBI:Mysql:mydb', 'myuser', 'mypass') do | dbh |
    dbh.do('CREATE TABLE slugs(name, age);')
    sql = "INSERT INTO slugs(name,age) VALUES(?,?)"
    dbh.prepare(sql) do |sth|
        1.upto(43) { |i| sth.execute("Slug #{i}", "#{i*3}")}
    end
    dbh.select_all('SELECT * FROM slugs;') do |row|
        puts "Hello, #{row[0]}"
    end
    sth = dbh.prepare("SELECT * FROM slugs WHERE name='Slug 1';")
    sth.execute
    while row = sth.fetch do
        puts row
    end
end

To start up DBI, call 'connect', feeding the database driver, the name of the database, the host to use, and open a block. This block is provided the database handle as a parameter.

First, we create a table to work with using the do method. The do method immediately executes the SQL statement. Next, we build a SQL statement and prepare it using the 'prepare' statement. This allow us to execute the same SQL statement over and over again quickly, and efficiently using the execute method. The 'select_all' method returns every row from a SELECT statement and feed it to a block. There is also a 'select_one' method for those times when you really just need one row.

Finally the block exits, and the client disconnects. If we opt to not use the block form of this code, we will need to call 'disconnect' to disconnect from the server.

What is ActiveRecord?

It is an ORM (Object Relational Mapping).

How to use ActiveRecord without Rails?

gem install activerecord

To get ActiveRecord going in your application, we construct a configuration that would normally live in a Rails database configuration file (i.e. config/database.yml), define your ActiveRecord classes, then call methods on them.

require 'rubygems'
require_gem 'activerecord'

ActiveRecord::Base.establish_connection(
    :adapter => "mysql",
    :host => "localhost",
    :database => "test",
    :username => "root",
    :password => ""
)

class Person < ActiveRecord::Base
end

people = Person.find(:all)
puts "Total: #{people.length}"

people.each do |personobj|
    puts "Hello #{personobj.name}, #{personobj.job}."
end

As you can see, rather than having pre-constructed configuration, the establish_connection method is fed a longer set of parameters. Then, the class that inherits from ActiveRecord::Base is created that is the singular form of the table name we made earlier, hence Person for the table 'people'. This maps the table to a class that you can instantiate and use to manipulate rows in the database.

How to extract a portion of a string?

a_str[0..2]
a_str[0,2]
a_str.slice(0,2)
a_str.slice(0..2)

How to convert a string to upper case?

a_str = a_str.upcase
a_str.upcase!

How to convert a string to lower case?

a_str.downcase
a_str.downcase!

How to swap case?

a_str = a_str.swapcase
a_str.swapcase!

How to capitalize a string?

a_str = a_str.capitalize
a_str.capitalize!

What is the significance of the exclamation mark at the end of a method name?

The exclamation mark at the end of a method name indicates that the method will modify the object itself.

What is the purpose of the squeeze method?

The squeeze method (of the string class) removes sets of the same character and replace them with a single character ("mess" is now "mes").

How to insert a string into another string?

str1 = "12345"
str1.insert(2,"LETTERS")
puts str1
--> 12LETTERS345

What is the purpose of the delete method?

You can use the delete method to remove characters or a range of characters from a string:

gone = "got gone fool!"
gone.delete("o", "r-v")
puts gone
--> g gone fl!

Placing a hyphen between two letters will tell Ruby to create an inclusive (i.e. also include the lower and upper limit characters, such as r and v in the example) range of characters. You can use this technique with a number of methods, but it is exceptionally useful with delete.

Notice that in the above example, the letter t is deleted, because it is part of the range r-v. The delete method can take multiple arguments, each can be a single characters, or a range of characters (range of characters is represented by a hyphen).

How to remove the new line character from the end of a string?

str.chomp

The 'chomp' method will remove the record separator, which is normally the newline character, stored in the global object $/, from the end of a string. If $/ hasn't been changed from the default, this means it will remove \n, \r\n, and \r. You can also specify what to 'chomp' by passing it in as a parameter as in the last example. The 'chop' method will simply chop off the last character regardless of what it is. It will treat the \r\n as one character.

How to remove white space from the beginning and / or the end of a string?

Use the lstrip, rstrip, or strip method:

str = " La di da! \t"
puts "[" + str.lstrip + "]"
-> [La di da! ]
puts "[" + str.rstrip + "]"
-> [ La di da!]
puts "[" + str.strip + "]"
-> [La di da!]

The lstrip, rstrip methods strip off any sort of whitespace (spaces, tabs, newlines, etc) from a string on the left or right side respectively. The strip method strips whitespace from both sides.

How to split a string by a character?

breakable = "break,it,down,fool!"
breakable.split(",")
--> ["break", "it", "down", "fool!"]

How to convert a string into a number?

Use the to_f and to_i methods:

numerical_string = "1234"
numerical_string + 6
-> ! TypeError
numerical_string.to_f + 6.7
-> 1240.7

All data read from sockets and files are strings. If we plan on doing any sort of math with this data, you must first convert it to number using to_f or to_i

How to determine the match position of a pattern within a string?

str = "I'm a cowboy, baby!"
str =~ /cow/
--> 6

str.match("cow")
--> #<MatchData:0x61d3120>

Using the =~ will return the index of the first match of the pattern, but using the match method of a string, you can get a MatchData object which gives you a number of options for accessing the matches:

message = "Hello there!"
message.match(/(..)(..)/).captures

Using the captures method, we can grab the matches for each expression.

How to extract the text between two delimiters?

html_element = "<html>"
element_text = html_element.match("(<)(.*)(>)").captures
puts element_text[1]
--> html

What is the purpose of the scan method of the string class?

message = "Hello there!"
message.scan(/(..)(..)/)
-->[["He", "ll"],["o ", "th"], ["er", "e!"]]

Notice that the scan method returns an array of matches, which are the text that are captured in the parantheses.

What are the differences between the match method and the scan method?

  1. The match method returns a MatchData object. The scan method returns an array of matches.
  2. The scan method is greedy. A "greedy" regular expression or method will match every occurrence of a pattern rather than just matching one. The scan method is greedy. It will match every occurrence of a pattern in a string.

What is the purpose of the sub and gsub methods?

go_away = "My name is Freak Nasty!"
go_away.sub("y","o")
-> Mo name is Freak Nasty!

go_away.gsub("y","o")
-> Mo name is Freak Nasto!

go_away.sub("Freak Nasty", "Fred Jones")
-> My name is Fred Jones!

The 'sub' method will only replace the first match for the pattern, but the 'gsub' method will replace every match

How to create a Date object?

mydate = Date.new(1999, 6, 4) -> 1999-06-04
mydatejd = Date.jd(2451334) -> 1999-06-04
mydateord = Date.ordinal(1999, 155) -> 1999-06-04
mydatecom = Date.commercial(1999, 22, 5) -> 1999-06-04
mydate = Date.parse("1999-06-04") -> 1999-06-04

The jd method allows you to create a Date instance based on a Julian day number. The 'ordinal' method creates a Date object based on the ordinal date (a date created by providing year and a day number within that year). The 'commercial' method creates a Date object from the provided commercial date (a date created by providing the year, the week number, and a day number).

How to access information from a date object?

mydate.mon
mydate.yday
mydate.day

How to compare two date objects?

date1 = Date.new(1985, 3, 18)
date2 = Date.new(1985, 5, 5)

date1 < date2 --> true
date1 == date2 --> false

What is the purpose of the « and the » operators when they are applied with a date object?

date1 << 3
date1 >> 5

We can use the » and « operator to add or substract months.

How to create an object that represent a timestamp?

rightnow = Time.new
Time.at(93493932)
Time.local(2000,"jan",1,20,15,1)
Time.utc(2006, 05, 21, 5, 13)
Time.parse("Tue Jun 13 14:15:01 Eastern Standard Time 2005")

We can create a Time object that holds the values for the current time and timezone by simply calling the 'new' method (or the 'now' method; they do the same thing). If you need a certain time, you can use the 'at' method, which operates on epoch time (seconds from January 1st, 1970. We can also use the 'utc' method, and the 'gm' method to creates times based on those timezones and provided parameters, or we can use the 'local' method to use the current local timezone. We can also use the 'parse' method to parse a timestamp string to create a Time object.

How to use strftime?

rightnow = Time.now
rightnow.strftime("%m/%d/%Y") --> 09/10/2006
rightnow.strftime("%I:%M%p") --> 09:13PM
rightnow.strftime("The %dth of %B in %y") --> The 17th of September in 06
rightnow.strftime("%x") --> 09/17/06

Hashing (MD5, SHA1):

require 'digest/md5'
md5 = Digest::MD5.digest('I have a fine vest!')
hexdigest = Digest::MD5.hexdigest('I have a fine vest!')
require 'digest/sha1'
sha1 = Digest::SHA1.digest('I have a fine vest!')
hexdigest = Digest::SHA1.hexdigest('I have a fine vest!')

How to implement encryption / decryption in Ruby?

gem install crypt

require 'crypt/blowfish'
blowfish = Crypt::Blowfish.new("A key up to 56 bytes long")
plainBlock = "ABCD1234"
encryptedBlock = blowfish.encrypt_block(plainBlock)
decryptedBlock = blowfish.decrypt_block(encryptedBlock)

The 'crypt' library offers four encryption algorithms: Blowfish, GOST, IDEA, and Rijndael. The interface for each one is relatively the same. See http://crypt.rubyforge.org.

How to do unit-testing?

class MacAddr
    def to_s
        return @mac_parts.join(":")
    end
    def initialize(mac)
        if (mac.length < 17)
            fail "MAC is too short.  Make sure colons are in place"
        end
        @mac_parts = mac.split(':')
    end
    def [](index)
        return @mac_parts[index]
    end
end

require 'test/unit'
class TestMac < Test::Unit::TestCase
    def test_tos
        assert_equal("FF:FF:FF:FF:FF:FF", MacAddr.new("FF:FF:FF:FF:FF:FF").to_s)
        assert_not_equal("FF:FF:00:FF:FF:FF", MacAddr.new("FF:FF:FF:FF:FF:FF").to_s)
    end
end

The test class is named with 'Test' followed by the name of the class being tested. The test class extends Test::Unit::TestCase. The test methods are named with the word 'test', followed by an underscore, and the name of the method being tested.

Each class should have its own test suite. As the number of test suites (classes) grow, we will want to break them into separate files. Fortunately, Test::Unit is smart enough to pick up on numerous test files being included into one test run:

require 'test/unit'
require 'pandatest'
require 'breakdancetest'
require 'breakdancingpandatest'

See http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.htm

References:

Books:
http://www.humblelittlerubybook.com/book/html/index.html

David Heinemeier Hansson - Ruby on Rails, Startups, Culture
Net::HTTP
Net::FTP
Net::SMTP
Net::POP
Net::IMAP
XML-RPC
Time
SOAP4R

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License