Monday, January 31, 2011

How to Dowload Ruby for windows?

For windows you can download Ruby
from

http://rubyforge.org/frs/?group_id=167

How to Dowload Ruby for Linux?

For windows you can download Ruby
from

http://rubyforge.org/frs/?group_id=167
for Linux try

http://www.rpmfind.net.

Saturday, January 29, 2011

Ruby scripting for beginners

Ruby Scripting for beginner
variables:-

We'll deal with variables in much more depth when we talk about classes and objects. For now, let's just say your basic local variable names should start with either a lower case letter or an underscore, and should contain upper or lower case letters, numbers, and underscore characters. Global variables start with a $.

Program flow:-

Ruby includes a pretty standard set of looping and branching constructs: if, while and case
For example, here's if in action:
a = 10 * rand

if a < 5 puts "#{a} less than 5" elsif a > 7
puts "#{a} greater than 7"
else
puts "Cheese sandwich!"
end
[As in other languages, the rand function generates a random number between 0 and 1]
There will be plenty more time to discuss conditional statements in later chapters. The above example should be pretty clear.
Ruby also includes a negated form of if called unless which goes something like
unless a > 5
puts "a is less than or equal to 5"
else
puts "a is greater than 5"
end
Generally speaking, Ruby keeps an if statement straight as long as the conditional (if ...) and the associated code block are on separate lines. If you have to smash everything together on one line, you'll need to place the then keyword after the conditional
if a < 5 then puts "#{a} less than 5" end if a < 5 then puts "#{a} less than 5" else puts "#{a} greater than 5" end Note that the if statement is also an expression; its value is the last line of the block executed. Therefore, the line above could also have been written as puts(if a < 5 then "#{a} less than 5" else "#{a} greater than 5" end) Ruby has also adopted the syntax from Perl where if and unless statements can be used as conditional modifiers after a statement. For example puts "#{a} less than 5" if a < 5 puts "Cheese sandwich" unless a == 4 while behaves as it does in other languages -- the code block that follows is run zero or more times, as long as the conditional is true while a > 5
a = 10*rand
end
And like if, there is also a negated version of while called until which runs the code block until the condition is true.
Finally there is the case statement which we'll just include here with a brief example. case is actually a very powerful super version of the if ... elsif... system
a = (10*rand).round
#a = rand(11) would do the same

case a
when 0..5
puts "#{a}: Low"
when 6
puts "#{a}: Six"
else
puts "#{a}: Cheese toast!"
end
There are some other interesting things going on in this example, but here the case statement is the center of attention.

functions:-


In keeping with Ruby's all-object-oriented-all-the-time design, functions are typically referred to as methods. No difference. We'll cover methods in much more detail when we get to objects and classes. For now, basic method writing looks something like this:
# Demonstrate a method with func1.rb
def my_function( a )
puts "Hello, #{a}"
return a.length
end

len = my_function( "Giraffe" )
puts "My secret word is #{len} long"
$ func1.rb
Hello, Giraffe
My secret word is 7 long
Methods are defined with the def keyword, followed by the function name. As with variables, local and class methods should start with a lower case letter.
In this example, the function takes one argument (a) and returns a value. Note that the input arguments aren't typed (i.e. a need not be a string) ... this allows for great flexibility but can also cause a lot of trouble. The function also returns a single value with the return keyword. Technically this isn't necessary -- the value of the last line executed in the function is used as the return value -- but more often than not using return explicitly makes things clearer.
As with other languages, Ruby supports both default values for arguments and variable-length argument lists, both of which will be covered in due time. There's also support for code blocks, as discussed below.

Blocks:-

One very important concept in Ruby is the code block. It's actually not a particularly revolutionary concept -- any time you've written if ... { ... } in C or Perl you've defined a code block, but in Ruby a code block has some hidden secret powers...
Code blocks in Ruby are defined either with the keywords do..end or the curly brackets {..}
do
print "I like "
print "code blocks!"
end

{
print "Me too!"
}
One very powerful usage of code blocks is that methods can take one as a parameter and execute it along the way.
[ed note: the Pragmatic Programmers actually want to point out that it's not very useful to describe it this way. Instead, the block of code behaves like a 'partner' to which the function occasionally hands over control]
The concept can be hard to get the first time it's explained to you. Here's an example:
$ irb --simple-prompt
>> 3.times { puts "Hi!" }
Hi!
Hi!
Hi!
=> 3
Surprise! You always thought 3 was just a number, but it's actually an object (of type Fixnum) As its an object, it has a member function times which takes a block as a parameter. The function runs the block 3 times.
Blocks can actually receive parameters, using a special notation |..|. In this case, a quick check of the documentation for times shows it will pass a single parameter into the block, indicating which loop it's on:
$ irb --simple-prompt
>> 4.times { |x| puts "Loop number #{x}" }
Loop number 0
Loop number 1
Loop number 2
Loop number 3
=> 4
The times function passes a number into the block. The block gets that number in the variable x (as set by the |x|), then prints out the result.
Functions interact with blocks through the yield. Every time the function invokes yield control passes to the block. It only comes back to the function when the block finishes. Here's a simple example:
# Script block2.rb

def simpleFunction
yield
yield
end

simpleFunction { puts "Hello!" }
$ block2.rb
Hello!
Hello!
The simpleFunction simply yields to the block twice -- so the block is run twice and we get two times the output. Here's an example where the function passes a parameter to the block:
# Script block1.rb

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }
$ block1.rb
Hello, Tiger
Hello, Giraffe
It might take a couple of reads through to figure out what's going on here. We've defined the function "animals" -- it expects a code block. When executed, the function calls the code block twice, first with the parameter "Tiger" then again with the parameter "Giraffe". In this example, we've written a simple code block which just prints out a greeting to the animals. We could write a different block, for example:
animals { |x| puts "It's #{x.length} characters long!" }
which would give:
It's 5 characters long!
It's 7 characters long!
Two completely different results from running the same function with two different blocks.
There are many powerful uses of blocks. One of the first you'll come across is the each function for arrays -- it runs a code block once for each element in the array -- it's great for iterating over lists.

How Ruby XPath to find attribute ?

What Ruby library can be used to select attribute using XPath, and to use it as the starting point for other XPath queries.

Example:






Desired code:

get_pair "//*/@key", "../@value"
get_pair "//*/@foo", "../@bar"
Expected output:

"A" "B"
"C" "D"
"E" "F"
Pseudo implementation:

def get_pair(key, value)
xml_doc.select[key].each do |a|
puts [a, a.select[value]]
end
end

Friday, January 28, 2011

How to deal with Java scripts and frame?

I came across this difficulty when I was trying to automate a webpage that was primarily built in Javascript; this webpage also always had the same href (or web address) and also was built with many frames. The problem that I ran into was that I could find the links with the IE developer toolbar to get their ids, but whenever I tried to access them, I could not, I was given an error message saying that they did not exist. At this point in time I thought the issue I had was with javascript, but I was incorrect!

A lot of hunting on the interwebs led me, ironically, back to the watir main documentation, where I discovered that my issue was really with frames! When a website has frames, you need to specify what frame the link is in to actually access it, for example:
ie.frame(“main”).link(:id,”UW_CO_JOBTITLE_HL$”).click

Or in general terms:
ie.frame(“FRAMENAME”).link(:id, “LINKID”).click

And there we have, you can now access links that are in frames, hopefully this saves someone all of the hunting that I had to do! This is also a really good example of how difficult it is to find a solution to something when you are not sure what the problem was; I thought the problem was with JavaScript, so I was searching for that, but it was in fact as stated above with the frames!

IE Automation testing with Ruby: How to catch popup windows?

Firstly I need to define what I mean my pop-up Windows. The pop-up windows that cause trouble are not internet explorer based windows, they are actually ‘Windows’ windows, (sorry if thats confusing). The ones that I am referring to are the ones that come up when, for example, you click on a download link. These are inherently a pain because of the fact that they are not IE windows. Luckily there is a pretty simple work around that i have come up with.

Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:

require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title

At this point you can manipulate the window, for example, with a SendKeys command:

wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4

This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.

Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!

require ‘win32ole’
require ‘watir’

wsh = WIN32OLE.new(‘Wscript.Shell’)

ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click

sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click

wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it

Watir::IE.close_all #Closes all open IE windows

How to catch Popup windows?

The pop-up windows that cause trouble are not internet explorer based windows, they are actually ‘Windows’ windows, (sorry if thats confusing). The ones that I am referring to are the ones that come up when, for example, you click on a download link. These are inherently a pain because of the fact that they are not IE windows. Luckily there is a pretty simple work around that i have come up with.

Ruby has access to the WIN32OLE library , which is basically like an API for windows applications. What you can do is use this library to catch these pop up windows. Below is the code that you’ll need to run in a Ruby script:

require ‘win32ole’ #Loads the win32ole library
wsh = WIN32OLE.new(Wscript.Shell) #For more info click here
wsh.AppActivate(‘Connect’) #Focuses on a given application based on its Title

At this point you can manipulate the window, for example, with a SendKeys command:

wsh.SendKeys(“%{F4}”) #This would close the program with Alt-F4

This clearly has it’s limitations because during this time you cannot be doing things on your computer, because the AppActivate would fail. I am still looking for a lower level at which I can address this problem.

Now everyone likes to see code at work, so I have written a quick script that goes to the Notepad++ downloads page, clicks the download link, and then closes the pop-up download window. As a quick side note, if you do not already use notepad++ I highly recommend it!

require ‘win32ole’
require ‘watir’

wsh = WIN32OLE.new(‘Wscript.Shell’)

ie= Watir::IE.new
ie.goto(“http://notepad-plus.sourceforge.net/uk/site.htm”)
ie.frame(:name, “index”).link(:text, “Download”).click #Good example of how to execute a link in a Frame
ie.frame(:name, “index”).link(:text, “Download Notepad++ executable files”).click

sleep 20 #need to wait for source forge to load it is slow
ie1 = Watir::IE.attach(:title, /Source/)
ie1.link(:id, “showfiles_download_file_pkg0_1rel0_2″).click

wsh.AppActivate(“File Download – Security Warning”) #Focuses on the pop up window
wsh.SendKeys(“%{F4}”) #Sends the alt-F4 command to the window to close it

Watir::IE.close_all #Closes all open IE windows

How to handle JavaScripts popups?

These JavaScript popups cause trouble as they interrupt the page from fully loading, causing Watir to wait (as the page is waiting), which means the next command in your script will never be reached. Previous work arounds to this were to use watirs built in click_no_wait, but I have that to be extremely temperamental and did not always work depending on which element the click was being performed on.

The new and improved method is to have a completely separate process that runs in the background and is continually checking for JavaScript pop ups. AutoIt commands are used to first locate the pop-up and then depending on what text or title is present in the pop up and different action can be performed on it. Unfortunately the same code cannot be used for both IE and FF due to the fact that the AutoIt controls cannot perform the same actions on IE pop-ups as it can on FF pop-ups. I have included the code for both below:

clickPopupsIE.rb

require 'win32ole'
begin
autoit WIN32OLE.new('AutoItX3.Control')
loop do
autoit.ControlClick("Windows Internet Explorer",'', 'OK')
autoit.ControlClick("Security Information",'', '&Yes')
autoit.ControlClick("Security Alert",'', '&Yes')
autoit.ControlClick("Security Warning",'', 'Yes')
autoit.ControlClick("Message from webpage",'', 'OK')
sleep 1
end
rescue Exception > e
puts e
end

clickPopupsFF.rb

require 'win32ole'
websiteName = "w3schools.com"
begin
autoit = WIN32OLE.new('AutoItX3.Control')
loop do
autoit.winActivate("The page at http://#{websiteName} says:")
autoit.Send("{ENTER}") if(autoit.WinWait("The page at http://#{websiteName} says:",'',2) == 1)
end
rescue Exception => e
puts e
end


These two scripts can then be called from any of your other Watir scripts using the following two functions scripts:

require 'win32/process'
def callPopupKillerFF
$pid = Process.create(:app_name => 'ruby clickPopupsFF.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end

def callPopupKillerIE
$pid = Process.create(:app_name => 'ruby clickPopupsIE.rb', :creation_flags => Process::DETACHED_PROCESS).process_id
end

def killPopupKiller
Process.kill(9,$pid)
end


As you can see above you do need to require one more ruby gem, ‘win32/process’, this is used to run the popup clicker as a separate process that runs in the background. Once you have those functions in place you can simply call:


callPopupKillerIE #Starts the IE popup killer
#Some watir code that results in a popup#
killPopupKiller #Kills the popup killer process, so that you do not end up with 5 of them running!

Ubuntu 8.10 With Firewatir

Some kind Ruby Enthusiasts built a tool called Watir (Web Application Testing in Ruby) which basically allows you to programmatically control a web browser (Specifically Microsoft Internet Explorer). From a Software Quality Assurance standpoint this allows the developers to automate much of what is typically a manual process.
However, IE is not the only browser in the world (and if I had my way it would be eliminated from the face of the earth), and thus has has grown related projects Such as FireWatir which runs Firefox instead of IE.
Last summer's google summer of code involved some refactoring of the Watir code to work more uniformely with FireWatir (and I believe the safari equivalent as well -- although I haven't used that so I can't confirm). Anyways, the process of using watir/firewatir is pretty simple. First, setup your requires/includes

view sourceprint?
1 #may not need rubygems if your system is setup right

2 require 'rubygems'

3 require 'watir'

4 require 'firewatir'

5

6 include FireWatir
Then you do

view sourceprint?
1 browser = Watir::Browser.new

2 #instead of browser = Watir::IE.new
For more information on Watir::Browser check this page:
http://wiki.openqa.org/display/WTR/Browser.new

Unfortunately it doesn't appear the RDocs have been updated to include Watir::Browser

This all works great on windows (who would have guessed), but I've been having trouble setting up Firefox to work with Firewatir in Ubuntu 8.10 linux. I've used several different JSSH extensions that are supposedly compatible with FF on linux (and they appear to install just fine). Those extensions can be found here:
http://wiki.openqa.org/display/WTR/FireWatir+Installation
and here:
http://www.valibuk.net/2008/11/jssh-firefox-30-with-optional-port-number/

Neither seem to work though. I've tried just about everything I can think of, but I can never get telnet to connect to port 9997 after I've loaded the extension into firefox (and restarted, and setup firefox preferences according to tutorials found
here
and
here
and several others. But nothing, I always get the following error when attempting to do either Firefox.new or Watir::Browser.new :

Watir::Exception::UnableToStartJSShException:
Unable to connect to machine : 127.0.0.1 on port 9997.
Make sure that JSSh is properly installed and Firefox
is running with '-jssh' option
I have yet to come up with a working solution, however I'm in the process of building firefox from source and enabling jssh in the build (which should solve the problem).

The build process I've essentially stolen from the firefox build process documentation and utilized from:
http://ubuntu-snippets.blogspot.com/2008/07/build-firefox-3-web-browser-...
and
https://developer.mozilla.org/En/Simple_build

Basically, I pull the source code with hg (mercurial), and use the newer build process documented on the mozilla site, while creating a .mozconfig file as noted in the other tutorial. The one change I had to make to the .mozconfig was I removed the webservices extension since it doesn't seem to be avaiable anymore (I was getting an error when I left it).

Anyways, if anyone has got JSSH working with ubuntu 8.10 I'd love to know how you did it.
Check back often as I shall report with news of whether or not this is working fairly soon.

--- Follow Up --3/22/2009
After finding out that selenium can now be used without using server side javascript code directly I switched to that. I'm now using that with cucumber and have come up with some cool ways of automating tests in multiple browsers. Check back soon, I should have a blog with some details on my setup.

--- Follow Up --4/30/2009

Friday, January 21, 2011

Ruby Scripting

variables:-

We'll deal with variables in much more depth when we talk about classes and objects. For now, let's just say your basic local variable names should start with either a lower case letter or an underscore, and should contain upper or lower case letters, numbers, and underscore characters. Global variables start with a $.

Program flow:-

Ruby includes a pretty standard set of looping and branching constructs: if, while and case
For example, here's if in action:
a = 10 * rand

if a < 5 puts "#{a} less than 5" elsif a > 7
puts "#{a} greater than 7"
else
puts "Cheese sandwich!"
end
[As in other languages, the rand function generates a random number between 0 and 1]
There will be plenty more time to discuss conditional statements in later chapters. The above example should be pretty clear.
Ruby also includes a negated form of if called unless which goes something like
unless a > 5
puts "a is less than or equal to 5"
else
puts "a is greater than 5"
end
Generally speaking, Ruby keeps an if statement straight as long as the conditional (if ...) and the associated code block are on separate lines. If you have to smash everything together on one line, you'll need to place the then keyword after the conditional
if a < 5 then puts "#{a} less than 5" end if a < 5 then puts "#{a} less than 5" else puts "#{a} greater than 5" end Note that the if statement is also an expression; its value is the last line of the block executed. Therefore, the line above could also have been written as puts(if a < 5 then "#{a} less than 5" else "#{a} greater than 5" end) Ruby has also adopted the syntax from Perl where if and unless statements can be used as conditional modifiers after a statement. For example puts "#{a} less than 5" if a < 5 puts "Cheese sandwich" unless a == 4 while behaves as it does in other languages -- the code block that follows is run zero or more times, as long as the conditional is true while a > 5
a = 10*rand
end
And like if, there is also a negated version of while called until which runs the code block until the condition is true.
Finally there is the case statement which we'll just include here with a brief example. case is actually a very powerful super version of the if ... elsif... system
a = (10*rand).round
#a = rand(11) would do the same

case a
when 0..5
puts "#{a}: Low"
when 6
puts "#{a}: Six"
else
puts "#{a}: Cheese toast!"
end
There are some other interesting things going on in this example, but here the case statement is the center of attention.

functions:-


In keeping with Ruby's all-object-oriented-all-the-time design, functions are typically referred to as methods. No difference. We'll cover methods in much more detail when we get to objects and classes. For now, basic method writing looks something like this:
# Demonstrate a method with func1.rb
def my_function( a )
puts "Hello, #{a}"
return a.length
end

len = my_function( "Giraffe" )
puts "My secret word is #{len} long"
$ func1.rb
Hello, Giraffe
My secret word is 7 long
Methods are defined with the def keyword, followed by the function name. As with variables, local and class methods should start with a lower case letter.
In this example, the function takes one argument (a) and returns a value. Note that the input arguments aren't typed (i.e. a need not be a string) ... this allows for great flexibility but can also cause a lot of trouble. The function also returns a single value with the return keyword. Technically this isn't necessary -- the value of the last line executed in the function is used as the return value -- but more often than not using return explicitly makes things clearer.
As with other languages, Ruby supports both default values for arguments and variable-length argument lists, both of which will be covered in due time. There's also support for code blocks, as discussed below.

Blocks:-

One very important concept in Ruby is the code block. It's actually not a particularly revolutionary concept -- any time you've written if ... { ... } in C or Perl you've defined a code block, but in Ruby a code block has some hidden secret powers...
Code blocks in Ruby are defined either with the keywords do..end or the curly brackets {..}
do
print "I like "
print "code blocks!"
end

{
print "Me too!"
}
One very powerful usage of code blocks is that methods can take one as a parameter and execute it along the way.
[ed note: the Pragmatic Programmers actually want to point out that it's not very useful to describe it this way. Instead, the block of code behaves like a 'partner' to which the function occasionally hands over control]
The concept can be hard to get the first time it's explained to you. Here's an example:
$ irb --simple-prompt
>> 3.times { puts "Hi!" }
Hi!
Hi!
Hi!
=> 3
Surprise! You always thought 3 was just a number, but it's actually an object (of type Fixnum) As its an object, it has a member function times which takes a block as a parameter. The function runs the block 3 times.
Blocks can actually receive parameters, using a special notation |..|. In this case, a quick check of the documentation for times shows it will pass a single parameter into the block, indicating which loop it's on:
$ irb --simple-prompt
>> 4.times { |x| puts "Loop number #{x}" }
Loop number 0
Loop number 1
Loop number 2
Loop number 3
=> 4
The times function passes a number into the block. The block gets that number in the variable x (as set by the |x|), then prints out the result.
Functions interact with blocks through the yield. Every time the function invokes yield control passes to the block. It only comes back to the function when the block finishes. Here's a simple example:
# Script block2.rb

def simpleFunction
yield
yield
end

simpleFunction { puts "Hello!" }
$ block2.rb
Hello!
Hello!
The simpleFunction simply yields to the block twice -- so the block is run twice and we get two times the output. Here's an example where the function passes a parameter to the block:
# Script block1.rb

def animals
yield "Tiger"
yield "Giraffe"
end

animals { |x| puts "Hello, #{x}" }
$ block1.rb
Hello, Tiger
Hello, Giraffe
It might take a couple of reads through to figure out what's going on here. We've defined the function "animals" -- it expects a code block. When executed, the function calls the code block twice, first with the parameter "Tiger" then again with the parameter "Giraffe". In this example, we've written a simple code block which just prints out a greeting to the animals. We could write a different block, for example:
animals { |x| puts "It's #{x.length} characters long!" }
which would give:
It's 5 characters long!
It's 7 characters long!
Two completely different results from running the same function with two different blocks.
There are many powerful uses of blocks. One of the first you'll come across is the each function for arrays -- it runs a code block once for each element in the array -- it's great for iterating over lists.

Frames in WATIR: watir Frames

we can find out, if our page have frmes by following techniques..

ie.show_frames
This is a good method to use with IRB. It prints out the index and the name of the frames in the current page. Like this:
irb(main):009:0> ie.show_frames
there are 2 frames
frame index: 1 name: menu
frame index: 2 name: main
=> 0..1


If you want to ask Watir directly which HTML elements it knows about, execute this code (contributed by Bret Pettichord at watir-general, works only on Windows):

require 'watir/ie'

def is_element_subclass? klass
while klass = klass.superclass
return true if klass == Watir::Element
end
end

ObjectSpace.each_object(Class){|c| puts c if is_element_subclass?(c)}
You should get this (for Watir 1.6.5):

Watir::Link
Watir::Image
Watir::TableCell
Watir::TableRow
Watir::TableBody
Watir::TableBodies
Watir::Table
Watir::CheckBox
Watir::Radio
Watir::RadioCheckCommon
Watir::FileField
Watir::Hidden
Watir::TextField
Watir::Button
Watir::SelectList
Watir::InputElement
Watir::Em
Watir::Strong
Watir::Dd
Watir::Dt
Watir::Dl
Watir::H6
Watir::H5
Watir::H4
Watir::H3
Watir::H2
Watir::H1
Watir::Ul
Watir::Li
Watir::Label
Watir::Area
Watir::Map
Watir::Span
Watir::Div
Watir::P
Watir::Pre
Watir::NonControlElement
Watir::Form

Thursday, January 20, 2011

Web Application Testing in Ruby: How to get Watir to return actual HTM, when site is redirecting??

Web Application Testing in Ruby: How to get Watir to return actual HTM, when site is redirecting??

Watir is working correctly in that case. There is no special user-agent or anything used by Watir because plain old IE is used and it's user-agent is sent by the IE itself of course.

The reason why you cannot find the checkbox with Watir or from the HTML is that the checkbox is in a frame :) Look for a frame tag in that html and you can understand why you were not able to find it before.

You can access it from the frame instead:

b.frame(:id, "download-frame").checkbox(:name, "21.1.9.12.3.1.3.0").clear
If you're getting access denied errors when trying to access frames

How to get Watir to return actual HTM, when site is redirecting??

Web Application Testing in Ruby: Iframe in Watir

ie = Watir::IE.new
ie.goto "http://www.apple.com/safari/download"

ie.checkbox(:name, "21.1.9.12.3.1.3.0").clear
Which returns an UnkownObjectException. Same with trying to click the submit button.

Using firebug I can find the checkbox fine, that's how I found the :name. So I next redirected the HTML output from Watir into a file for inspection,

myfile = File.new("safaridebug.html", "w+")
myfile.puts ie.html
myfile.close

Iframe in Watir

"Watir allows access to frame objects by identifying them by their name
attribute. This is the form that Watir takes to access a frame:
ie.frame("menu")

To access individual objects within that frame, you prefix the object
using the Watir code above. If we had a hyperlink in the menu frame:
Click Menu Item, we could click it like this:
ie.frame("menu").link(:text, "Click Menu Item").click


See [installation dir]/watir_bonus/doc/watir_user_guide.html

How can i know which method is called?

Web Application Testing in Ruby: Web Application Testing in Ruby: How to get frame name from Index

you send a message to an object, Ruby follows some path along
singleton object, class, included modules, superclasses, and so on.
Is there a way to know where the responding method is defined?

For example:

obj = MyClass.new
....
obj.f

The method f could be defined in MyClass or it could be just obj's
singleton method or whatever.
Is there a way to be sure of it?

I think I can find which class or module newly define a method.
But I don't know whether a method is redefined by a class or module

Web Application Testing in Ruby: How to get frame name from Index

Web Application Testing in Ruby: Frames

print ie.show_frames
---------------------------------------------
frame index: 1 name: leftFrame
frame index: 2 name: topFrame
frame index: 3 name: mainFrame
---------------------------------------------

frameCount = ie.document.frames.length
ar = Array.new(frameCount)
counter = 1

while counter <= frameCount
ar[counter] = ie.frame(:index, counter)
counter = counter + 1
end

I am able to pull info about a specific frame by using ie.frame(:index,
1) but when using this in the loop above I receive the following error:
Unable to locate a frame with name #

This is confusing to me since I am not specifying the name of the frame
but rather the index and I'm not sure why Watir is comparing the names.
I really just need a way to find out how to obtain the name of a frame
using its index.

As always I really appreciate any suggestions or ideas. Thanks!


Are you donig something like this later in the script:

ie.frame( ar[1] )

if so, thats already a watir::frame object

so you probably need

ar[1].button(xxxx).click

Web Application Testing in Ruby:Ruby is very object oriented language

Web Application Testing in Ruby: Web Application Testing in Ruby: Catch and Throw

In my opinion, objects are all about data. In programs using objects to simulate real world things like cannonballs, such data might be position, velocity and mass. In business programs, an object might contain a person's first and last name, employee number, job classification and health insurance.

An object is a wonderful place to store a program's configuration information. All such info is kept in one place such that only a single object is kept global or passed in and out of subroutines.

All of these ideas precede object orientation. Since the dawn of time programmers have put all data for an entity in a data structure, and then manipulated the structure. Here's some code I wrote in 1986 to manipulate the page of a dot matrix printer. Keep in mind that back in those days, computers didn't have enough RAM for everyone to store their printed page in an 80x66 array. Much of my job back then was programming computers to print out medical insurance forms, each with about 40 boxes to fill out in very tight quarters. There were several different form layouts, and they changed frequently. So here's some 1986 C code (note the original K&R style -- no prototypes):
/* THE REPORT VARIABLE */
typedef struct
{
FILE *fil; /* report file file variable */
int y; /* y coord on page, changed only by atyxpr */
int x; /* x coord on page, changed only by atyxpr */
int pglength; /* lines per page, changed only by openrpt */
int stringlength; /* maximum length of string to be printed */
int lineno; /* line number, changed only by applcatn pgmr */
int pageno; /* page number, changed only by applictn pgmr */
char status[10]; /* set to @REPORT or @CLOSED */
} REPORT;


void atyxpr(rpt,y,x,st)
REPORT *rpt; /* the report variable pointer */
int y; /* the present vertical print position */
int x; /* the present horizontal print position */
char *st; /* the string to be printed */

{
int i;

checkopen(rpt);
if ((x == 0) && (y == 0))
{ /* continue printing at last position */
y = rpt->y;
x = rpt->x;
}

/* formfeed if the print line you're seeking is higher than the last time */
if (y < rpt->y)
formfeed(rpt);

/* insert a '^' if you've overwritten a column */
if ((y == rpt->y) && (x < rpt->x))
{
strcpy(st, st +(1 + rpt->x - x));
writestring(rpt, "^");
x = rpt->x;
fprintf(stderr, "?-warning-atyxpr- column overwrite in line %d.\n", rpt->y);
}

/* bring the print position to the new coordinates */
while (y > rpt->y)
{
linefeed(rpt->fil);
rpt->y = rpt->y + 1;
rpt->x = 1;
}
while (x > rpt->x)
{
spaceout(rpt->fil);
rpt->x = rpt->x + 1;
}

/* do the actual write of the string */
writestring(rpt, st);

/* bring the x position up to date after the write */
rpt->x = rpt->x + strlen(st);
} The REPORT structure kept track of the current position of the print head (y and x), the number of lines on a page (pglength), and the file to which to write the output (the file was usually a printer device). All this information remained persistent in the report structure.

The report structure was manipulated by a function called atyxpr(),. To print a string at a specific line and column, the programmer specified the string to print and the y and x coordinates (row and column) at which to start printing the string. Also specified was the report structure.

If the row and column were specified as both being 0, atyxpr() printed the string at the current print head position, as if the print was done by a simple printf().

If the row was the same as the current printhead row but the column was farther out, atyxpr() printed spaces until the printer head was in the desired place, and then the string was printed.

If the desired row was below the current printhead position, atyxpr() printed linefeeds to get to the desired row, printed spaces to get to the desired column, and then printed the string.

If the desired row was above the current printhead position, that meant that it needed to be printed on the next page, so a formfeed was issued, then enough linefeeds to get to the desired row, then enough spaces to get to the desired column, and then the string was printed.

What does this have to do with Ruby? Believe it or not, there's a purpose to showing this obsolete C code from an era of monospace printers and computers too anemic to store 80x66 worth of characters. That purpose is to show that there's absolutely nothing new about congregating all data about a specific entity or device in a single place, nor is there anything new about encapsulation. You do not need object orientation to do these things. I did it in 1986 using K&R C, and people were doing it long before me.

What IS new about object oriented programming (OOP) is that you can store the subroutines that manipulate the data (atyxpr() in this example) right along with the data. But so what? What's the advantage?

The advantage is something called namespace collision. The name of the subroutine manipulating the data is in scope only within the context of that data. If that name is used elsewhere, it refers to a different subroutine. In old C, if you had geometric figures square, circle, point and parabola, look what you'd need:
• circle_move(circleVar, fromy, fromx, toy, tox)
• square_move(squareVar, fromy, fromx, toy, tox)
• point_move(parabolaVar, fromy, fromx, toy, tox)
• parabola_move(parabolaVar, fromy, fromx, toy, tox)
You need to remember four subroutine names (circle_move, square_move, point_move, and parabola_move), none of which is especially memorable. Now consider an object oriented language, where objects circle, square, point and parabola each implement their own move routine:
• circle.move(fromy, fromx, toy, tox)
• square.move(fromy, fromx, toy, tox)
• point.move(fromy, fromx, toy, tox)
• parabola.move(fromy, fromx, toy, tox)
In Object Oriented Programming (OOP), move means move -- it's intuitive.

Others will state additional benefits. They'll tell of the ability to redefine operators depending on the types being manipulated. They'll speak of inheritance, where you can create a new object type that's an enhancement of one already made, and you can even create a family of similar object types that can be manipulated by same named, similar performing subroutines. These are all nice, but in my opinion the only essentials are encapsulation and reduction of namespace collision.

Many tout OOP for purposes of reusability. I disagree. Everyone's talking about reusable code, but few are writing it, with OOP or anything else. Reusability is harder to find than the fountain of youth. If OOP were really that reusable, that wouldn't be true.
Classes and Objects
Think of a class as a set of architectural drawings for a house. Think of objects as the houses built according to those drawings. The drawings can be used as a plan for many, many houses. Not only that, the houses needn't be the same. Some can have carpeting, some have wood floors, but they were all created from the drawings. Once the house is created, the owner can put in a 14 cubic foot refrigerator or a 26 foot one. The owner can put in the finest entertainment center, or a 14" TV with rabbit ears on a wooden crate. No matter, they were all made from the same drawings. The drawing is the class, the house is the object.

A class is a plan to create objects. Ideally it lists all the data elements that will appear in any of its objects. It lists any subroutines the objects will need to manipulate the data. Those subroutines are called methods in OOP speak. It might even give the data elements initial values so that if the programmer doesn't change them, he has intelligent defaults. But typically, the computer program changes at least some of those data elements while it's being run.
Simple OOP in Ruby
In Ruby, a class begins with the class keyword, and ends with a matching end. The simplest class that can be made contains nothing more than the class statement and corresponding end:
class Myclass
end
The preceding class would not error out, but it does nothing other than tell the name of its class:
#!/usr/bin/ruby
class Myclass
end

myclass = Myclass.new
print myclass.class, "\n"
[slitt@mydesk slitt]$ ./hello.rb
Myclass
[slitt@mydesk slitt]$

To be useful, a class must encapsulate data, giving the programmer methods (subroutines associated with the class) to read and manipulate that data. As a simple example, imagine a class that produces objects that maintain a running total. This class maintains one piece of data, called @total, which is the total being maintained. Note that the at sign (@) designates this variable as an instance variable -- a variable in scope only within objects of this class, and persistent within those objects.

This class has a method called hasTotal() that returns true if the total is defined, false if it's nil. That way you can test to make sure you don't perform operations on a nil value. It also has getTotal() to read the total. It has setTo() to set the total to the argument of setTo(), it has methods increaseBy() and multiplyBy() add or multiply the total by an argument.

Last but not least, it has initialize()., which is called whenever Total.new() is executed. This happens because initialize() is a special reserved name -- you needn't do anything to indicate it's a constructor. The number of arguments in initialize() is the number of arguments Total.new() expects. The other thing that happens in initialize() is that all the instance variables are declared and initialized (in this case to the argument passed in through new().

Here is the code:
#!/usr/bin/ruby
class Total
def initialize(initial_amount)
@total=initial_amount
end

def increaseBy(increase)
@total += increase
end

def multiplyBy(increase)
@total *= increase
end

def setTo(amount)
@total = amount
end

def getTotal() return @total; end
def hasTotal() return @total!=nil; end
end

total = Total.new(0)
for ss in 1..4
total.increaseBy(ss)
puts total.getTotal if total.hasTotal
end
print "Final total: ", total.getTotal, "\n" if total.hasTotal
[slitt@mydesk slitt]$ ./hello.rb
1
3
6
10
Final total: 10
[slitt@mydesk slitt]$

The main routine instantiates an object of type Total, instantiating the total to a value of 0. Then a loop repeatedly adds the loop subscript to the total, printing each time after the add. Finally, outside the loop, the total is printed, which is 10, otherwise known as 1+2+3+4.

Take some time to study the preceding example, and I think you'll find it fairly self-explanatory.

Now for a little controversy. Remember I said you declare all instance variables inside initialize()? You don't have to. You could declare them in other methods:
#!/usr/bin/ruby
class Total
def initialize(initial_amount)
@total=initial_amount
end

def setName(name) @name = name; end
def hasName() return @name != nil; end
def getName() return @name; end

def increaseBy(increase)
@total += increase
end

def multiplyBy(increase)
@total *= increase
end

def setTo(amount)
@total = amount
end

def getTotal() return @total; end
def hasTotal() return @total!=nil; end
end

total = Total.new(15)
print total.getTotal(), "\n"
print total.getName(), "\n"
total.setName("My Total")
print total.getName(), "\n"
[slitt@mydesk slitt]$ ./hello.rb
15
nil
My Total
[slitt@mydesk slitt]$

From a viewpoint of pure modularity, readability and encapsulation, you'd probably want to have all instance variables listed in the initialize() method. However, Ruby gives you ways to access instance variables directly, either read-only or read-write. Here's a read only example:
#!/usr/bin/ruby
class Person
def initialize(lname, fname)
@lname = lname
@fname = fname
end

def lname
return @lname
end
def fname
return @fname
end
end

steve = Person.new("Litt", "Steve")
print "My name is ", steve.fname, " ", steve.lname, ".\n"
[slitt@mydesk slitt]$ ./hello.rb
My name is Steve Litt.
[slitt@mydesk slitt]$

You and I know fname and lname are accessed as methods, but because they're read as steve.fname, it seems like you're directly reading the data. Now let's go for a read/write example:

#!/usr/bin/ruby
class Person
def initialize(lname, fname)
@lname = lname
@fname = fname
end

def lname
return @lname
end

def fname
return @fname
end

def lname=(myarg)
@lname = myarg
end

def fname=(myarg)
@fname = myarg
end
end

steve = Person.new("Litt", "Stove")
print "My name is ", steve.fname, " ", steve.lname, ".\n"
steve.fname = "Steve"
print "My name is ", steve.fname, " ", steve.lname, ".\n"

When I instantiated the object in the preceding code, I accidentally spelled my name "Stove". So I changed it as if it were a variable. This behavior was facilitated by the def lname=(arg) method. The output of the preceding code follows:
[slitt@mydesk slitt]$ ./hello.rb
My name is Stove Litt.
My name is Steve Litt.
[slitt@mydesk slitt]$

The methods facilitating the seeming ability to write directly to the data are called accessor methods. Because accessor methods are so common, Ruby has a shorthand for them:
#!/usr/bin/ruby
class Person
def initialize(lname, fname)
@lname = lname
@fname = fname
end

attr_reader :lname, :fname
attr_writer :lname, :fname
end

steve = Person.new("Litt", "Stove")
print "My name is ", steve.fname, " ", steve.lname, ".\n"
steve.fname = "Steve"
print "My name is ", steve.fname, " ", steve.lname, ".\n"
[slitt@mydesk slitt]$ ./hello.rb
My name is Stove Litt.
My name is Steve Litt.
[slitt@mydesk slitt]$

In the preceding code, the variables after attr_reader substituted for the readonly accessor members, while the attr_writer substituted for the writeonly accessor members. Notice that when you write the names of the instance variables, you substitute a colon for the instance variables' at signs. There is actually a syntax reason, consistent with Ruby, for this substitution, but I can't explain it, so I choose to just remember it.

Remember, this seeming direct access must be explicitly enabled by the class's programmer, so this usually doesn't compromise encapsulation beyond what needs to be available. In my opinion this is a really handy option.
Inheritance
Inheritance is where a more specific kind of class is made from a more general one. For instance, an employee is a kind of person. Specifically (and oversimplistically), it's a person with an employee number. See this inheritance example:
#!/usr/bin/ruby
class Person
def initialize(lname, fname)
@lname = lname
@fname = fname
end

attr_reader :lname, :fname
attr_writer :lname, :fname
end

class Employee < Person # Declare Person to be parent of Employee
def initialize(lname, fname, empno)
super(lname, fname) # Initialize Parent's (Person) data
# by calling Parent's initialize()
@empno = empno # Initialize Employee specific data

end
attr_reader :empno # Accessor for employee specific data
attr_writer :empno # Accessor for employee specific data
# Parent's data already given accessors
# by parent class definition
end

steve = Employee.new("Litt", "Steve", "12345")
print steve.fname, " ", steve.lname, " is employee number ", steve.empno, ".\n"
[slitt@mydesk slitt]$ ./hello.rb
Steve Litt is employee number 12345.
[slitt@mydesk slitt]$

Ruby REALLY makes inheritance easy. On the class line you declare the child class's parent. In the child class's initialize() you call the parent's initializer by the super(supers_args) syntax. Because the parent's data is initialized and available to the child, you needn't redeclare accessor methods for the parent's data -- only for the child's data. In other words, in the child class you need code only for data specific to the child. It's handy, intuitive, and smooth.
Redefining Operators
It is nice to have total.add() and total.increaseBy() methods. But in many cases it's even more intuitive to use the + or += operator. In C++ it's always somewhat difficult to remember how to redefine operators. Not so in Ruby:
#!/usr/bin/ruby
class Total
def getTotal() return @total; end
def hasTotal() return @total!=nil; end
def initialize(initial_amount)
@total=initial_amount
end

def increaseBy(b)
@total += b
end

def add(b)
if b.class == Total
return Total.new(@total + b.getTotal())

else
return Total.new(@total + b)
end
end

def +(b)
self.add(b)
end

def *(b)
if b.class == Total
return Total.new(@total * b.getTotal())

else
return Total.new(@total * b)
end
end
end

total5 = Total.new(5)
total2 = Total.new(2)
total3 = Total.new(3)

myTotal = total5 + total2 + total3
print myTotal.getTotal(), "\n"

myTotal *= 2
print myTotal.getTotal(), "\n"

myTotal += 10
print myTotal.getTotal(), "\n"

In the preceding, we define add() as returning the argument plus @total. Notice that @total is not changed in-place. We might want to add add a Total to the existing Total, or we might want to add an integer. Therefore, Total::add() checks the argument's type, and if it's a Total it adds the argument's value, otherwise it adds the argument.

With add() safely defined, we now define + as basically a synonym for add(). The fascinating thing about Ruby is that if you define +, you get += free of charge, without further coding, and += does the right thing. As of yet I have not found a way to redefine +=, or any other punctuation string more than one character long. Luckily, += "just does the right thing", consistent with the definition of +.

It's not necessary to define a word function before redefining an operator, as the * operator (really a method) in the preceding code shows. Once again, it has an if statement so that integers or Totals can be added.

In the main part of the routine, we test by creating three totals with values 5, 2 and 3 repectively. We then add them together to create myTotal, which should be 10 and indeed is. We then in-place multiply by 2 to get the expected 20, and then in-place add 10 to get the expected 30:
[slitt@mydesk slitt]$ ./hello.rb
10
20
30
[slitt@mydesk slitt]$

Web Application Testing in Ruby: Catch and Throw

Web Application Testing in Ruby: Web Application Testing in Ruby: What is Ecxeption in Ruby??

Catch and Throw
The catch and throw keywords enable you to jump up the error stack, thereby in effect performing a goto. If you can think of a good reason to do this, research these two keywords on your own. Personally, I'd prefer to stay away from them.

We've just scratched the surface of exception handling, but you probably have enough now to at least write simple exceptions and read other people's exception code.
Terminal IO
This section will cover just a few of the many ways you can do terminal IO. You've already learned about print and puts:
#!/usr/bin/ruby
print "This is the first half of Line 1. "
print "This is the second half.", "\n"
puts "This is line 2, no newline necessary."

The preceding code produces the following result:
[slitt@mydesk slitt]$ ./hello.rb
This is the first half of Line 1. This is the second half.
This is line 2, no newline necessary.
[slitt@mydesk slitt]$

Ruby has a printf() command similar to C:
#!/usr/bin/ruby
printf "There were %7d people at the %s.\n", 439, "Avalanche Auditorium"
[slitt@mydesk slitt]$ ./hello.rb
There were 439 people at the Avalanche Auditorium.
[slitt@mydesk slitt]$

You get line oriented keyboard input with gets:
#!/usr/bin/ruby
print "Name please=>"
name = gets
print "Your name is ", name, "\n"
[slitt@mydesk slitt]$ ./hello.rb
Name please=>Steve Litt
Your name is Steve Litt

[slitt@mydesk slitt]$

You can get a single character with gets(). However, the user will need to press the Enter key before gets() will accept the character. To enable instantaneous recognition of the character, you must set cbreak before gets() and then reset it afterwards, like this:
#!/usr/bin/ruby
print "Character please=>"
system "stty cbreak /dev/tty 2>&1";
int = STDIN.getc
system "stty -cbreak /dev/tty 2>&1";
print "\nYou pressed >", int, "<, char >", int.chr, "<\n"
[slitt@mydesk slitt]$ ./hello.rb
Character please=>A
You pressed >65<, char >A<
[slitt@mydesk slitt]$

The cbreak commands seem to work on modern Linuces. They are VERY system dependent, and as far as I know don't work on Windows at all. On some Unices you might try these instead:
system "stty", '-icanon', 'eol', "\001";
int = STDIN.getc
system "stty", 'icanon', 'eol', '^@'; # ASCII null
Terminal I/O is pretty simple in Ruby. So is file I/O...
File IO
File I/O uses the File object. It's very straightforward, as you can see from the following program, which opens resolv.conf for input, andjunk.jnk for output, and then copies each line from the input file to the output file:
#!/usr/bin/ruby
infile = File.new("/etc/resolv.conf", "r")
outfile = File.new("junk.jnk", "w")
infile.each {
|i|
outfile.write i
}
outfile.close()
infile.close()

outfile = File.new("junk.jnk", "r")
outfile.each {
|i|
print ">>", i
}
[slitt@mydesk slitt]$ ./hello.rb
>>search domain.cxm
>>nameserver 192.168.100.103
>>
>># ppp temp entry
[slitt@mydesk slitt]$

Perl has a way to immediately read a whole file into an array, and so does Ruby:
#!/usr/bin/ruby
infile = File.new("/etc/resolv.conf", "r")
linearray = infile.readlines
linearray.each{|i| print i}
infile.close
[slitt@mydesk slitt]$ ./hello.rb
search domain.cxm
nameserver 192.168.100.103

# ppp temp entry
[slitt@mydesk slitt]$

Ruby can no also read one character at a time:
#!/usr/bin/ruby
infile = File.new("/etc/resolv.conf", "r")
infile.each_byte {
|i|
if i.chr == "e"
print("!")
else
print(i.chr)
end
}
infile.close
[slitt@mydesk slitt]$ ./hello.rb
s!arch domain.cxm
nam!s!rv!r 192.168.100.103

# ppp t!mp !ntry
[slitt@mydesk slitt]

If for some reason you don't want to use the each construct, you can use readchar like this:
#!/usr/bin/ruby
infile = File.new("/etc/resolv.conf", "r")
until infile.eof
i = infile.readchar
if i.chr == "e"
print("!")
else
print(i.chr)
end
end
infile.close

In the preceding code, the eof method looks ahead to see whether the next character read will be valid, and if so, loops through, reads and prints it. You might think of doing a priming read, then putting the next read at the bottom of the loop, testing for i==nil. Unfortunately, if you read into the end of file, it triggers an exception which prints an error message, and nobody wants that. Instead, use eof to look ahead and read just enough.

It isn't demonstrated in this tutorial, but you can use readline to read a line at a time, again using eof to look ahead.
[slitt@mydesk slitt]$ ./hello.rb
s!arch domain.cxm
nam!s!rv!r 192.168.100.103
nam!s!rv!r 209.63.57.200

# ppp t!mp !ntry
[slitt@mydesk slitt]$

How OOP is Ruby?
You hear it all the time. "Ruby's a purely Object Oriented language!"

On some levels that's a true statement, but it's misleading. It misled me into staying away from Ruby for three years.

See, to me "purely OOP" means a language you can't write procedural code with. Java, for instance, where you need to create a class to write a "hello world" program, and you can't make a subroutine outside of a class.

Ruby's not like that. A Ruby "hello world" program is two lines, you can write subroutines outside of any class that are accessible anywhere, and if you'd like you can write complete and complex programs without creating a single class or object.

In Ruby's case, what they mean by "purely OOP" is that all variables are objects. Integers, floating point numbers, characters, strings, arrays, hashes, files -- they're all objects. You manipulate these objects with their methods, not with Ruby built in operators. For instance, in the following:
profit = revenue - expense
In the preceding, profit, revenue and expense are all objects of class Float. The minus sign (-) is not a Ruby operator -- it's a method of the Float class. In the C language, the minus sign would be an operator supplied by the language, but in Ruby it's just a method of the Float class. Incidentally, a plus sign method is implemented in class Fixnum integers, where once again it adds the value, and in the String class, where it concatinates strings.

So Ruby's "purely OOP" in that when you use it you'll definitely be using objects, but you do not need to create objects to write a substantial Ruby programmer. So if you do not consider yourself an Object Oriented programmer, or even if you hate OOP, don't let that stop you from using Ruby.

Web Application Testing in Ruby: What is Ecxeption in Ruby??

Web Application Testing in Ruby: What is Subroutines in Ruby??
ExceptionsGrowing up with C, I wrote code for every possible error condition. Or, when I was too lazy to write code for error conditions, my code was less robust.

The modern method of error handling is with exceptions, and Ruby has that feature. Use them.

There are two things you can do: handle an exception, and raise an exception. You raise an exception by recognizing an error condition, and then associating it with an exception type. You usually don't need to raise an exception because most system calls already raise exceptions on errors. However, if you've written a new bit of logic, and encounter a forbidden state, then you would raise an exception.

You handle an exception that gets raised -- typically by system calls but possibly by your code. This handling is only for protected code starting with begin and ending with end. Here's a simple example:
#!/usr/bin/ruby
begin
input = File.new("/etc/resolv.conf", "r")
rescue
print "Failed to open /etc/fstab for input. ", $!, "\n"
end
input.each {
|i|
puts i;
}
input.close()

The preceding code produces the following output:
[slitt@mydesk slitt]$ ./hello.rb
search domain.cxm
nameserver 192.168.100.103

# ppp temp entry
[slitt@mydesk slitt]$

However, if the filename in File.new() is changed to the nonexistent /etc/resolX.conf, the output looks like this:
[slitt@mydesk slitt]$ ./hello.rb
Failed to open /etc/fstab for input. No such file or directory - /etc/resolX.conf
./hello.rb:7: undefined method `each' for nil:NilClass (NoMethodError)
[slitt@mydesk slitt]$

Global variable $!i had the value "No such file or directory - /etc/resolX.con", so that printed along with the error message in the rescue section. This exception was then passed to other exception handlers, that wrote additional messages and eventually terminated the program.

Exceptions are implemented as classes (objects), all of whom are descendents of the Exception class. Some have methods over and above those of the Exception class, some do not. Here is a list of the exceptions I was able to find in documentation on the web:
• ArgumentError
• IndexError
• Interrupt
• LoadError
• NameError
• NoMemoryError
• NoMethodError
• NotImplementedError
• RangeError
• RuntimeError
• ScriptError
• SecurityError
• SignalException
• StandardError
• SyntaxError
• SystemCallError
• SystemExit
• TypeError

The following is a more generic error handling syntax:
begin
# attempt code here
rescue SyntaxError => mySyntaxError
print "Unknown syntax error. ", mySyntaxError, "\n"
# error handling specific to problem here
rescue StandardError => myStandardError
print "Unknown general error. ", myStandardError, "\n"
# error handling specific to problem here
else
# code that runs ONLY if no error goes here
ensure
# code that cleans up after a problem and its error handling goes here
end
In the preceding, variables mySyntaxError and myStandardError are local variables to store the contents of global variable $!, the exception that was raised.
Retry
There's a retry keyword enabling a retry on error. This is handy when performing an activity that might benefit from a retry (reading a CD, for instance):
begin
# attempt code here
rescue
puts $!
if EscNotPressed()
print "Reload the CD, or press ESC\n"
retry
else
puts "User declined to retry further"
end
end
Raising an Exception
Sometimes the neither the system nor the language detect an error, but you do. Perhaps the user input someone 18 years old for Medicare. Linux doesn't know that's wrong. Ruby doesn't know that's wrong. But you do.

You can raise a generic exception (or the current exception if there is one) like this:
raise if age < 65
#!/usr/bin/ruby
age = 18
raise if age < 66
print "Age is ", age, ". This happens after the exception was raised\n"
[slitt@mydesk slitt]$ ./hello.rb
./hello.rb:3: unhandled exception
[slitt@mydesk slitt]$

To raise a RuntimeError exception with your own message, do this:
raise "Must be 65 or older for Medicare"
#!/usr/bin/ruby
age = 18
raise "Must be 65 or older for Medicare." if age < 66
print "Age is ", age, ". This happens after the exception was raised\n"
[slitt@mydesk slitt]$ ./hello.rb
./hello.rb:3: Must be 65 or older for Medicare. (RuntimeError)
[slitt@mydesk slitt]$

To raise a RangeError exception (you wouldn't really do this), you'd do this:
raise RangeError, "Must be 65 or older for Medicare", caller
#!/usr/bin/ruby
age = 18
raise RangeError, "Must be 65 or older for Medicare", caller if age < 66
print "Age is ", age, ". This happens after the exception was raised\n"
[slitt@mydesk slitt]$ ./hello.rb
./hello.rb:3: Must be 65 or older for Medicare (RangeError)
[slitt@mydesk slitt]$

Perhaps the best way to do it is to create a new exception class specific to the type of error:
#!/usr/bin/ruby
class MedicareEligibilityException < RuntimeError
end

age = 18
raise MedicareEligibilityException , "Must be 65 or older for Medicare", caller if age < 66
print "Age is ", age, ". This happens after the exception was raised\n"
[slitt@mydesk slitt]$ ./hello.rb
./hello.rb:6: Must be 65 or older for Medicare (MedicareEligibilityException)
[slitt@mydesk slitt]$

Now let's combine raising and handling, by creating a subroutine called signHimUp(), which raises the exception, and the calling main routine, which handles. In this particular, rather contrived program, information about the person whose information raised the exception is stored in the exception itself, by the initialize() method, which assigns its arguments to the class's instance variables, so that this call:
myException = MedicareEligibilityException.new(name, age)
creates an instance of class MedicareEligibilityException whose instance variables contain the person's name and age for later reference. Once again, this is very contrived, but it illustrates some of the flexibility of exception handling:
#!/usr/bin/ruby
class MedicareEligibilityException < RuntimeError
def initialize(name, age)
@name = name
@age = age
end
def getName
return @name
end
def getAge
return @age
end
end

def writeToDatabase(name, age)
# This is a stub routine
print "Diagnostic: ", name, ", age ", age, " is signed up.\n"
end

def signHimUp(name, age)

if age >= 65
writeToDatabase(name, age)
else
myException = MedicareEligibilityException.new(name, age)
raise myException , "Must be 65 or older for Medicare", caller
# raise MedicareEligibilityException , "Must be 65 or older for Medicare", caller
end
end

# Main routine
begin
signHimUp("Oliver Oldster", 78)
signHimUp("Billy Boywonder", 18)
signHimUp("Cindy Centurinarian", 100)
signHimUp("Bob Baby", 2)

rescue MedicareEligibilityException => elg
print elg.getName, " is ", elg.getAge, ", which is too young.\n"
print "You must obtain an exception from your supervisor. ", elg, "\n"

end

print "This happens after signHimUp was called.\n"

In the preceding code, the main routine calls subroutine signHimUp for each of four people, two of whom are underage. The begin/rescue/end structure in the main routine allows exceptions of type MedicateEligibilityException to be handled cleanly, although such exceptions are raised by the called subroutine, signHimU(). , signHimU(). routine tests for age 65 and older, and if so, calls dummy writeToDatabase() and if not, creates a new instance of MedicateEligibilityException containing the person's name and age, and then raises that exception, with the hope that the calling routine's exception handling will be able to use that information in its error message.

The MedicateEligibilityException definition itself is a typical class definition, with instance variables beginning with @, an initialize() constructor that assigns its arguments to the instance variables, and get routines for the instance variables. All of this will be covered later when we discuss classes and objects.

Here is the result:
[slitt@mydesk slitt]$ ./hello.rb
Diagnostic: Oliver Oldster, age 78 is signed up.
Billy Boywonder is 18, which is too young.
You must obtain an exception from your supervisor. Must be 65 or older for Medicare
This happens after signHimUp was called.
[slitt@mydesk slitt]$

As you can see, the first call to signHimUp() successfully ran the stub write to database routine, as indicated by the diagnostic line. The next call to signHimUp() encountered an exceptio MedicateEligibilityException exception, and the code in the rescue block got the patient's name and age from the exception, and wrote it. At that point the begin block was terminated, and execution fell through to the line below the end matching the exception handling's begin. If we had wanted to, we could have terminated the program from within the rescue block, in many ways, including ending that block with a raise command, or to bail immediately, an exit command.

What is Subroutines in Ruby??

Subroutines
A subroutine starts with def and ends with a corresponding end. Subroutines pass back values with the return keyword. In a welcome change from Perl, variables declared inside a subroutine are local by default, as shown by this program:
#!/usr/bin/ruby
def passback
howIfeel="good"
return howIfeel
end

howIfeel="excellent"
puts howIfeel
mystring = passback
puts howIfeel
puts mystring

In the preceding, note that the puts command writes the string and then prints a newline, as opposed to the print command, which doesn't print a newline unless you add a newline to the string being printed.

If the howIfeel variable inside subroutine passback were global, then after running the subroutine, the howIfeel variable in the main program would change from "excellent" to good. However, when you run the program you get this:
[slitt@mydesk slitt]$ ./hello.rb
excellent
excellent
good
[slitt@mydesk slitt]$

The first and second printing of the howIfeel variable in the main program both print as "excellent", while the value passed back from the subroutine, and stored in variable mystring prints as "good", as we'd expect. Ruby's variables are local by default -- a huge encapsulation benefit.

You can pass variables into a subroutine as shown in the following code:
#!/usr/bin/ruby
def mult(multiplicand, multiplier)
multiplicand = multiplicand * multiplier
return multiplicand
end

num1 = 4
num2 = 5
result = mult(num1, num2)
print "num1 is ", num1, "\n"
print "num2 is ", num2, "\n"
print "result is ", result, "\n"
[slitt@mydesk slitt]$ ./hello.rb
num1 is 4
num2 is 5
result is 20
[slitt@mydesk slitt]$

The value of num1 was not changed by running mult(), showing that arguments are passed by value, not reference, at least for integers. But what about for objects like strings?
#!/usr/bin/ruby
def concat(firststring, secondstring)
firststring = firststring + secondstring
return firststring
end

string1 = "Steve"
string2 = "Litt"
result = concat(string1, string2)
print "string1 is ", string1, "\n"
print "string2 is ", string2, "\n"
print "result is ", result, "\n"
[slitt@mydesk slitt]$ ./hello.rb
string1 is Steve
string2 is Litt
result is SteveLitt
[slitt@mydesk slitt]$

Once again, manipulations of an argument inside the subroutine do not change the value of the variable passed as an argument. The string was passed by value, not reference.

Ruby language for beginners

Containers:-

Containers are entities that contain other entities. Ruby has two native container types, arrays and hashes. Arrays are groups of objects ordered by subscript, while hashes are groups of key->value pairs. Besides these two native container types, you can create your own container types.
Arrays
You've already seen how to initialize an array and how to use the each method to quickly iterate each element:
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
presidents.each { |i| print i, "\n"}

[slitt@mydesk slitt]$ ./array.rb
Ford
Carter
Reagan
Bush1
Clinton
Bush2
[slitt@mydesk slitt]$

Now let's manipulate the array, starting by deleting the last three presidents:
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
presidents.pop
presidents.pop
presidents.pop
presidents.each { |i| print i, "\n"}

The pop method deletes the final element. If you were to assign the pop method to a variable, it would store that last element and then delete it from the array. In the preceding code, you pop the last three presidents. Here is the result:
[slitt@mydesk slitt]$ ./array.rb
Ford
Carter
Reagan
[slitt@mydesk slitt]$

Now let's prepend the previous three presidents, Kennedy, Johnson and Nixon:
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
presidents.pop
presidents.pop
presidents.pop
presidents.unshift("Nixon")
presidents.unshift("Johnson")
presidents.unshift("Kennedy")
presidents.each { |i| print i, "\n"}

The result is as expected:
[slitt@mydesk slitt]$ ./array.rb
Kennedy
Johnson
Nixon
Ford
Carter
Reagan
[slitt@mydesk slitt]$

However, you might not like the idea of prepending in the reverse order. In that case, prepend all three at once:
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
presidents.pop
presidents.pop
presidents.pop
presidents.unshift("Kennedy", "Johnson", "Nixon")
presidents.each { |i| print i, "\n"}

Ruby arrays have methods shift, unshift, push, and pop:
METHOD ACTION ARGUMENT RETURNS
push Appends its argument to the end of the array. Element(s) to be appended to end of the array. A string consisting of the concatination of all non-nil elements in the array AFTER the action was taken.
pop Returns the last element in the array and deletes that element. None. The last element of the array.
shift Returns the first element of the array, deletes that element, and shifts all other elements down one location to fill its empty spot. None. The first element in the array.
unshift Shifts all elements of the array up one, and places its argument at the beginning of the array. Element(s) to be prepended to start of array. A string consisting of the concatination of all non-nil elements in the array AFTER the action was taken.

You can assign individual elements of an array:
#!/usr/bin/ruby
presidents = []
presidents[2] = "Adams"
presidents[4] = "Madison"
presidents[6] = "Adams"
presidents.each {|i| print i, "\n"}
print "=======================\n"
presidents[6] = "John Quincy Adams"
presidents.each {|i| print i, "\n"}
print "\n"

The preceding code produces this output:
[slitt@mydesk slitt]$ ./array.rb
nil
nil
Adams
nil
Madison
nil
Adams
=======================
nil
nil
Adams
nil
Madison
nil
John Quincy Adams

[slitt@mydesk slitt]$

The length of the array is the determined by the last initialized element, even if that element was initialized to nil. That can be very tricky, especially because if you read past the end of the array it returns nil. Be careful.

You can insert an element by assignment, as shown in the preceding code. If you assign to an element that already exists, you simply change its value, as we changed "Adams" to "John Quincy Adams".

Another thing you can do is get a slice of an array.
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
p123=presidents[1..3]
p123.each { |i| print i, "\n"}

Notice this time I used the two period version of the elipses operator, so you'd expect it to list Carter, Reagan and Bush1, and indeed it does. The preceding slice produces the following output:
[slitt@mydesk slitt]$ ./array.rb
Carter
Reagan
Bush1
[slitt@mydesk slitt]$

Another way to slice an array is with a start and a count instead of a range. The following is another way to write basically the same code as the preceding code:
#!/usr/bin/ruby
presidents = ["Ford", "Carter", "Reagan", "Bush1", "Clinton", "Bush2"]
p123=presidents[1,3]
p123.each { |i| print i, "\n"}

The preceding used a starting subscript of 1 and a count of 3, instead of a range 1 through 3.

You can also use slices in insertions, deletions and replacements, and you can insert/replace with elements or whole arrays. Our first example deletes unneeded elements from the middle of an array:
#!/usr/bin/ruby
numbers = ["one", "two", "buckle", "my", "shoe", "three", "four"]
numbers.each { |i| print i, "\n"}
print "=====================\n"
numbers[2,3]=[]
numbers.each { |i| print i, "\n"}

In the preceding, we have extraneous elements "buckle", "my" and "shoe", which we want to delete. So we replace element 2, for a count of 4 (element 2 and the next 2, in other words), to an empty array, effectively deleting them. The result follows:

[slitt@mydesk slitt]$ ./array.rb
one
two
buckle
my
shoe
three
four
=====================
one
two
three
four
[slitt@mydesk slitt]$

Next, let's replace three numeric representations with their spelled out equivalents, plus add in another element we had forgotten:
#!/usr/bin/ruby
numbers = ["one", "two", "3", "4", "5", "seven"]
numbers.each { |i| print i, "\n"}
print "=====================\n"
numbers[2,3]=["three", "four", "five", "six"]
numbers.each { |i| print i, "\n"}

You can see we deleted the three numerics, and then added the four spelled out versions in their place. Here's the output:
[slitt@mydesk slitt]$ ./array.rb
one
two
3
4
5
seven
=====================
one
two
three
four
five
six
seven
[slitt@mydesk slitt]$

But what if you don't want to replace anything -- what if you just want to insert in the middle? No problem -- use 0 for the count...
#!/usr/bin/ruby
numbers = ["one", "two", "five"]
numbers.each { |i| print i, "\n"}
print "=====================\n"
numbers[2,0]=["three", "four"]
numbers.each { |i| print i, "\n"}

The only trick here is that if you are not deleting the starting point element, the insertion will occur AFTER the starting element. Here is the output:
[slitt@mydesk slitt]$ ./array.rb
one
two
five
=====================
one
two
three
four
five
[slitt@mydesk slitt]$

You might ask yourself what to do if you need to append before the first element, given that slice type insertion inserts AFTER the starting point. The simplest answer is to use the unshift method.

You can construct an array using a parenthesized range:

#!/usr/bin/ruby
myArray = (0..9)
myArray.each{|i| puts i}
[slitt@mydesk slitt]$ ./array.rb
0
1
2
3
4
5
6
7
8
9
[slitt@mydesk slitt]$

Finally, remembering that Ruby is intended to be an object oriented language, let's look at some of the more common methods associated with arrays (which are really objects in Ruby):
#!/usr/bin/ruby
numbers = Array.new
numbers[3] = "three"
numbers[4] = nil
print "Class=", numbers.class, "\n"
print "Length=", numbers.length, "\n"
numbers.each { |i| print i, "\n"}

The Array.new method types numbers as an array. You could have done the same thing with numbers=[]. The next line assigns text three to the element with subscript 3, thereby setting the element and also setting the array's length. The next line sets the element whose subscript is 4 to nil, which, when you view the output, will prove that the length method returns one plus the last initialized element, even if it's initialized to nil. This, in my opinion, could cause trouble.

The class method returns the variable's class, which in a non-oop language could be thought of as its type. The following is the output:
[slitt@mydesk slitt]$ ./hello.rb
Class=Array
Length=5
nil
nil
nil
three
nil
[slitt@mydesk slitt]$

We've gone through arrays in great detail, because you'll use them regularly. Now it's time to review Ruby's other built in container class...
Hashes
There are two ways to think of a hash:
1. A set of key->value pairs
2. An array whose subscripts aren't necessarily ordered or numeric
Both of the preceding are correct, and do not conflict with each other.
#!/usr/bin/ruby
litt = {"lname"=>"Litt", "fname"=>"Steve", "ssno"=>"123456789"}
print "Lastname : ", litt["lname"], "\n"
print "Firstname : ", litt["lname"], "\n"
print "Social Security Number: ", litt["ssno"], "\n"
print "\n"
litt["gender"] = "male"
litt["ssno"] = "987654321"
print "Corrected Social Security Number: ", litt["ssno"], "\n"
print "Gender : ", litt["gender"], "\n"
print "\n"
print "Hash length is ", litt.length, "\n"
print "Hash class is ", litt.class, "\n"

In the preceding, we initialized the hash with three elements whose keys were lname, fname and ssno. We later added a fourth element whose key was gender, as well as correcting the value of ssno. The class and length methods do just what we'd expect, given our experience from arrays. This hash could be thought of as a single row in a database table. Here is the result:
[slitt@mydesk slitt]$ ./hash.rb
Lastname : Litt
Firstname : Litt
Social Security Number: 123456789

Corrected Social Security Number: 987654321
Gender : male

Hash length is 4
Hash class is Hash
[slitt@mydesk slitt]$


Better yet, hashes values can be other types of classes. For instance, consider a hash of hashes:
#!/usr/bin/ruby
people = {
"torvalds"=>{"lname"=>"Torvalds", "fname"=>"Linus", "job"=>"maintainer"},
"matsumoto"=>{"lname"=>"Matsumoto", "fname"=>"Yukihiro", "job"=>"Ruby originator"},
"litt"=>{"lname"=>"Litt", "fname"=>"Steve", "job"=>"troubleshooter"}
}

keys = people.keys

for key in 0...keys.length
print "key : ", keys[key], "\n"
print "lname: ", people[keys[key]]["lname"], "\n"
print "fname: ", people[keys[key]]["fname"], "\n"
print "job : ", people[keys[key]]["job"], "\n"
print "\n\n"
end

Here's the output:
[slitt@mydesk slitt]$ ./hash.rb
key : litt
lname: Litt
fname: Steve
job : troubleshooter


key : matsumoto
lname: Matsumoto
fname: Yukihiro
job : Ruby originator


key : torvalds
lname: Torvalds
fname: Linus
job : maintainer


[slitt@mydesk slitt]$

Basically, you just implemented the equivalent of a database table, whose rows correspond to Litt, Matsumoto and Torvalds, and whose columns are lname, fname and job. There are probably a dozen better ways to actually print this information, but at this point I'm still learning Ruby, so I did it with a distinctively Perl accent. Perhaps that's a good thing -- it proves that Ruby follows ordinary programming logic in addition to its many wonderful features.
Sorting Hashes
You sort hashes by converting them to 2 dimensional arrays -- an array of key/value pairs, and then sorting them. The sort method does just that. Here's an example:
#!/usr/bin/ruby -w

h = Hash.new
h['size'] = 'big'
h['color'] = 'red'
h['brand'] = 'ford'

av = h.sort{|a,b| a[1] <=> b[1]}
ak = h.sort{|a,b| a[0] <=> b[0]}
ak.each do
|pair|
print pair[0]
print "=>"
print pair[1]
puts
end
puts "=============="
av.each do
|pair|
print pair[0]
print "=>"
print pair[1]
puts
end [slitt@mydesk ~]$ ./test.rb
brand=>ford
color=>red
size=>big
==============
size=>big
brand=>ford
color=>red
[slitt@mydesk ~]$ Notice that often a simple <=> command does not suffice, and you actually need to write your own function to establish collation order. Simply write a function taking two arguments (a and b) that returns 1 when a is superior to b, -1 when a is inferior to b, and 0 when they are equivalent.
Tests and Info Requests on Hashes
Method What it does Synonyms
has_key?(key) Tests whether the key is present in the hash. include?(key), key?(key) and member?(key)
has_value?(value) Tests whether any element of the hash has the value, returning true or false. value?(value)
index(value) Returns the key for an element with the value. I don't know what happens if multiple elements have that value.
select {|key, value| block} => array Returns an array of key/value pairs for which block evaluates true:
h.select {|k,v| v < 200} empty? Returns True if no key/value pairs inspect Return contents of the hash as a string invert Returns a new hash with keys and values switched. length How many key/value pairs does it have? size() sort {| a, b | block } => array


Strings
Strings are a class that ship with Ruby. The String class has a huge number of methods, such that memorizing them all would be futile. If you really want a list of them all, go http://www.rubycentral.com/book/ref_c_string.html., but don't say I didn't warn you.

What I'd like to do here is give you the 10% of strings you'll need for 90% of your work. By the way, Ruby has regular expressions, and that will be covered in the following section. This section covers only Ruby's String class methods.

Let's start with string assignment and concatination:
#!/usr/bin/ruby
myname = "Steve Lit"
myname_copy = myname
print "myname = ", myname, "\n"
print "myname_copy = ", myname_copy, "\n"
print "\n=========================\n"
myname << "t" print "myname = ", myname, "\n" print "myname_copy = ", myname_copy, "\n" The double less than sign is a Ruby String overload for concatination. If all goes well, we'll change the original string but the copy won't change. Let's verify that: [slitt@mydesk slitt]$ ./string.rb myname = Steve Lit myname_copy = Steve Lit ========================= myname = Steve Litt myname_copy = Steve Litt [slitt@mydesk slitt]$ Oh, oh, it changed them both. String assignment copies by reference, not by value. Do you think that might mess up your loop break logic? Use the String.new() method instead: #!/usr/bin/ruby myname = "Steve Lit" myname_copy = String.new(myname) print "myname = ", myname, "\n" print "myname_copy = ", myname_copy, "\n" print "\n=========================\n" myname << "t" print "myname = ", myname, "\n" print "myname_copy = ", myname_copy, "\n" Here's the proof that it works the way you want it: [slitt@mydesk slitt]$ ./hello.rb myname = Steve Lit myname_copy = Steve Lit ========================= myname = Steve Litt myname_copy = Steve Lit [slitt@mydesk slitt]$ One really nice thing about the Ruby String class is it works like an array of characters with respect to splicing: #!/usr/bin/ruby myname = "Steve was here" print myname[6, 3], "\n" myname[6, 3] = "is" print myname, "\n" [slitt@mydesk slitt]$ ./string.rb was Steve is here [slitt@mydesk slitt]$ This gets more powerful when you introduce the index string method, which returns the subscript of the first occurrence of a substring: #!/usr/bin/ruby mystring = "Steve was here" print mystring, "\n" substring = "was" start_ss = mystring.index(substring) mystring[start_ss, substring.length] = "is" print mystring, "\n" In the preceding, the start point for replacement was the return from the index method, and the count to replace is the return from the length method (on the search text). The result is a generic replacement: [slitt@mydesk slitt]$ ./string.rb Steve was here Steve is here [slitt@mydesk slitt]$ Naturally, in real life you'd need to add code to handle cases where the search string wasn't found. You already saw in-place concatenation with the << method, but in addition there's the more standard plus sign concatenation: #!/usr/bin/ruby mystring = "Steve" + " " + "was" + " " + "here" print mystring, "\n" [slitt@mydesk slitt]$ ./string.rb Steve was here [slitt@mydesk slitt]$ If the addition sign means to add strings together, it's natural that the multiplication sign means string together multiple copies: #!/usr/bin/ruby mystring = "Cool " * 3 print mystring, "\n" [slitt@mydesk slitt]$ ./string.rb Cool Cool Cool [slitt@mydesk slitt]$ Do you like the sprintf() command in C? Use the % method in Ruby: #!/usr/bin/ruby mystring = "There are %6d people in %s" % [1500, "the Grand Ballroom"] print mystring, "\n [slitt@mydesk slitt]$ ./string.rb There are 1500 people in the Grand Ballroom [slitt@mydesk slitt]$ You can compare strings: #!/usr/bin/ruby print "frank" <=> "frank", "\n"
print "frank" <=> "fred", "\n"
print "frank" <=> "FRANK", "\n"
[slitt@mydesk slitt]$ ./hello.rb
0
-1
1
[slitt@mydesk slitt]$

Here are some other handy string methods:

mystring.capitalize Title case. Returns new string equal to mystring except that the first letter of every word is uppercase
mystring.capitalize! Title case in place.
mystring.center(mynumber) Returns a new string mynumber long with mystring centered within it. If mynumber is already less than the length of mystring, returns a copy of mystring.
mystring.chomp Returns a new string equal to mystring except any newlines at the end are deleted. If chomp has an argument, that argument serves as the record separator, replacing the default newline.
mystring.chomp! Same as chomp, but in place. Equivalent of Perl chomp().
mystring.downcase Returns new string equal to mystring but entirely lower case.
mystring.downcase! In place modifies mystring, making everything lower case.
mystring.reverse Returns new string with all characters reversed. IOWA becomes AWOI.
mystring.reverse! Reverses mystring in place.
mystring.rindex(substring) Returns the subscript of the last occurrence of the substring. Like index except that it returns the last instead of first occurrence. This method actually has more options, so you might want to read the documentation.
mystring.rjust(mynumber) Returns a copy of mystring, except the new copy is mynumber long, and mystring is right justified in that string. If mynumber is smaller than the original length of mystring, it returns an exact copy of mystring.
mystring.split(pattern, limit) Returns a new array with parts of the string split wherever pattern was encountered as a substring. If limit is given, returns at most that many elements in the array.
mystring.strip Returns a new string that is a copy of mystring except all leading and trailing whitespace have been removed.
mystring.to_f Returns the floating point number represented by mystring. Returns 0.0 if it's not a valid number, and never raises exceptions. Careful!
mystring.to_i Returns an integer represented by mystring. Non-numerics at the end are ignored. Returns 0 on invalid numbers, and never raises exceptions. Careful!
mystring.upcase Returns a new string that's an uppercase version of mystring.
mystring.upcase! Uppercases mystring in place.



There are many, many more methods, but the preceding should get you through most programming tasks. If you end up using Ruby a lot, it would help to learn all the methods.

A word about mystring.split(pattern). What about the reverse -- turning an array into a string? Try this:
#!/usr/bin/ruby
mystring=""
presidents = ["reagan", "bush1", "clinton", "bush2"]
presidents.each {|i| mystring << i+" "}
mystring.strip
print mystring, "\n"
[slitt@mydesk slitt]$ ./string.rb
reagan bush1 clinton bush2
[slitt@mydesk slitt]$

Here's a version that turns it into a comma delimited file with quotes:
#!/usr/bin/ruby
mystring=""
presidents = ["reagan", "bush1", "clinton", "bush2"]
presidents.each {|i| mystring << "\"" + i + "\", "}
mystring[mystring.rindex(", "), 2] = ""
print mystring, "\n"
[slitt@mydesk slitt]$ ./string.rb
"reagan", "bush1", "clinton", "bush2"
[slitt@mydesk slitt]$

You now know most of the Ruby string techniques you need for the majority of your work. Well, except for regular expressions, of course...
Regular Expressions

NOTE

This section assumes you understand the concept of regular expressions. If you do not, there are many fine regular expression tutorials on the web, including this one on my Litt's Perls of Wisdom subsite.

Regular expressions make life so easy, often replacing 100 lines of code with 5. Perl is famous for its easy to use and intuitive regular expressions.

Ruby is a little harder because most regular expression functionality is achieved by a regular expression object that must be instantiated. However, you CAN test for a match the same as in Perl:
#!/usr/bin/ruby
string1 = "Steve was here"
print "e.*e found", "\n" if string1 =~ /e.*e/
print "Sh.*e found", "\n" if string1 =~ /Sh.*e/
[slitt@mydesk slitt]$ ./regex.rb
e.*e found
[slitt@mydesk slitt]$


Here's the code to actually retrieve the first match of /w.ll/ in the string:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
if string1 =~ /(w.ll)/
print "Matched on ", $1, "\n"
else
puts "NO MATCH"
end
[slitt@mydesk slitt]$ ./regex.rb
Matched on will
[slitt@mydesk slitt]$

This was almost just like Perl. You put parentheses in the regular expression to make a group, perform the regular expression search with the =~ operator, and then the match for the group is contained in the $1 variable. If there had been multiple groups in the regular expressions, matches would have also been available in $2, $3, and so on, up to the number of groups in the regular expression.


The more OOPish method of doing all this is to instantiate a new Regexp object and using its methods to gain the necessary information:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
regex = Regexp.new(/w.ll/)
matchdata = regex.match(string1)
if matchdata
puts matchdata[0]
puts matchdata[1]
else
puts "NO MATCH"
end

[slitt@mydesk slitt]$ ./hello.rb
will
nil
[slitt@mydesk slitt]$

If you change /w.ll/ to /z.ll/, which of course does not match because there's not a "z" in string1, the output looks like this:

[slitt@mydesk slitt]$ ./hello.rb
NO MATCH
[slitt@mydesk slitt]$
The preceding example shows how to do complete regex in Ruby. Start by creating a regular expression object using Regexp.new(). Then use that object's match method to find a match and return it in a MatchData object. Test that the MatchData object exists, and if it does, get the first match (matchdata[0]). The reason we also printed matchdata[1] was to show that, in the absense of groups surrounded by parentheses, the match method returns only a single match. Later you'll see a special way to return all matches of a single regular expression.

Another thing to notice is that, in Ruby, matching is not greedy by default. It finds the shortest string that satisfies the regular expression. If Ruby's matching was greedy like Perl's, the match would have included the entire string:

"will drill for a well in walla wall"

In other words, it would have returned everything from the first w to the last double l. Ungreedy matches go along with Ruby's principle of least surprise, but sometimes what you want is greedy matching.

You can return several matches using multiple groups, like this:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
regex = Regexp.new(/(w.ll).*(in).*(w.ll)/)
matchdata = regex.match(string1)
if matchdata
for ss in 0...matchdata.length
puts matchdata[ss]
end
else
puts "NO MATCH"
end
[slitt@mydesk slitt]$ ./hello.rb
will drill for a well in walla wall
will
in
wall
[slitt@mydesk slitt]$

Note the different behavior when you use parentheses. Here you see that the 0 subscript element matches the entire regular expression, while elements 1, 2 and 3 are the individual matches for the first, second and third parenthesized groups.

What if you wanted to find ALL the matches for /w.ll/ in the string, without guessing beforehand how many parentheses to put in? Here's the way you do it:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
regex = Regexp.new(/w.ll/)
matchdata = regex.match(string1)
while matchdata != nil
puts matchdata[0]
string1 = matchdata.post_match
matchdata = regex.match(string1)
end
[slitt@mydesk slitt]$ ./regex.rb
will
well
wall
wall
[slitt@mydesk slitt]$

What you've done here is repeated the match, over and over again, each time assigning the remainder of the string after the match to string1 via the post_match method. The loop terminates when no match is found.
Regex Substitution
My research tells me Ruby's regular expressions do not, in and of themselves, have a provision for substitution. From what I've found, you need to use Ruby itself, specifically the String.gsub() method, to actually perform the substitution. If that's true, to me that represents a significant hassle, although certainly not a showstopper. If I'm wrong about this, please let me know.

The following makes all occurrences of /w.ll/ uppercase in the string:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
string1.gsub!(/(w.ll)/){$1.upcase}
puts string1
[slitt@mydesk slitt]$ ./hello.rb
I WILL drill for a WELL in WALLa WALLa washington.
[slitt@mydesk slitt]$

The preceding depends on the block form of the String.gsub() method. I could not get the non-block form to accept the matches of the regular expression.

If you had wanted to replace only the first occurrence of /w.ll/, you would have had to do this (warning, ugly!):
#!/usr/bin/ruby
puts string1
regex = Regexp.new(/w.ll/)
match = regex.match(string1)
offsets = match.offset(0)
startOfMatch = offsets[0]
endOfMatch = offsets[1]
string1[startOfMatch...endOfMatch] = match[0].upcase
puts string1
[slitt@mydesk slitt]$ ./regex.rb
I WILL drill for a well in walla walla washington.
[slitt@mydesk slitt]$

Being a Perl guy, I'm used to having the regular expression do the entire substitution in a single line of code, and find the preceding quite cumbersome. Obviously, some of the preceding code was inserted just for readability. For instance, I could have done this:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
match = /w.ll/.match(string1)
string1[match.offset(0)[0]...match.offset(0)[1]] = match[0].upcase
puts string1

Or even this, which I'm sure would have fit right in with K&R first edition:
#!/usr/bin/ruby
string1 = "I will drill for a well in walla walla washington."
match = /w.ll/.match(string1)
string1[/w.ll/.match(string1).offset(0)[0].../w.ll/.match(string1).offset(0)[1]] = match[0].upcase
puts string1

If you can read the preceding, you're a better programmer than I.

In my opinion, Ruby beats the daylights out of Perl in most aspects, but not in regular expressions.