This tutorial assumes:
- Ruby 1.8.0 or
greater is installed on your system.
- You are interested in learning about Komodo functionality,
including the debugger.
- You are interested in Ruby and have some programming
experience either in Ruby or another language.
The Ruby Tutorial demonstrates how to use Komodo to write and
debug a simple Ruby program which saves it's data in a YAML file.
In this tutorial you will:
- Open the Ruby
Tutorial Project.
- Analyze
menagerie.rb the Ruby program included in the
Tutorial Project.
- Run the
program in Komodo.
- Debug the
program using the Komodo debugger.
See Debugging Programs
for more information on debugging in Komodo.
On the File menu, click
Open|Project and select
ruby_tutorial.kpf
from
<installdir>r\samples\ruby_tutorials
. All
files included in the tutorial project are displayed on the
Projects tab in the
Left Pane.
The ruby_tutorial project contains:
- menagerie.rb: A program which stores and
retrieves information on animals.
- animals.yaml: A YAML data file containing
a base list of animals.
- check_fname: A code snippet that can be
added to the program.
On the Projects tab,
double-click the menagerie.rb file. This file opens in
the Editor Pane; a tab at the top of the pane displays the
filename.
The menagerie.rb program is a simple interactive
program that can add, list, and search for information about
animals. It can also store this information in a YAML file (e.g.
animals.yaml). It is essentially an extremely simple
database with predefined fields.
In this step, you will analyze the program in sections. Ensure
that line numbers are enabled in Komodo (View|View Line
Numbers) and that the file menagerie.rb is
displayed in the Komodo editor.
Line 6 - Importing the YAML class
- This line loads Ruby's core YAML class.
Komodo Tip: Notice that syntax
elements are displayed in different colors. You can
adjust the display options for language elements in the
Preferences
dialog box.
|
Line 8 to 13 - Define and Initialize the Entry class
The Entry class contains variables which hold
data for individual entries in our simple database, and the
behavior of that data. Information about each animal in our
menagerie will be contained in an Entry class object.
class Entry
declares the class
- the initialize method sets the instance
variables
@sci_name
, @desc
, and
@time_mod
.
These variables need to be private (instance
variables) rather than global because there will be an instance
of the Entry class for each animal in the menagerie.
Line 15 - Expose instance variables
- attr_reader is a Ruby shortcut for
exposing
@sci_name
, @desc
, and
@time_mod
as read-only attributes of the Entry
class.
Line 18 to 26 - Data Storage Methods
- the sci_name= method ensures that
@time_mod
is updated with the current time
whenever @sci_name
is updated.
- the desc= method does the same thing for
@desc
.
Komodo Tip: Click on the minus symbol
to the left of line 18. The section of code for the
sci_name method is collapsed. Doing this
at line 8 collapses the entire Entry
class. This is called Code Folding.
|
Line 28 to 35 - Data Behavior Methods
- the contains? method lets the
cmd_search method determine if a particular
entry contains the string the user entered (see line 82).
- the to_sci method returns the scientific
name and description of an entry (see lines 77 and 83).
Line 39 to 46 - Command Help
- the $help global variable contains a
string with information on command usage, providing an easy way
for methods to display help information when needed.
Line 48 to 55 - Define and Initialize the Menagerie
class
The Menagerie class contains the
@menagerie hash: the container which holds the
multiple instances of the Entry class. It also
contains all the methods available to the user of the application
(via the command interface starting at line 154.
class Menagerie
declares the class
- initialize sets the instance variables
@menagerie
and @fname
.
The name of the animal is stored as a key in the
@menagerie
hash. It references the
Entry object which contains the rest of the
information, namely the scientific name (sci_name
)
and description (descr
). All the information we
store on each animal is kept in two separate areas -- the
@menagerie
key and the Entry it
points to.
Line 57 to 69 - Adding Entries
- the split method (from Ruby's String
class) allows us to enter an entire record in one line,
specifying the separator character we intend to use
- line 60 checks for an existing entry of the same name
- if none is found, a new entry (i.e. Entry.new) is
added
- if there is an existing key of the same name, the entry is
only updated if there is a change to
sci_name
or
descr
(or both)
Exercise: After completing the
tutorial, come back to this section and try writing a
more "user friendly" version of this
cmd_add method which asks for the name,
scientific name and description separately (i.e. one at a
time).
|
Line 74 to 88 - Searching for Entries
- line 75 checks to make sure an argument has been
provided
- line 76 searches
@menagerie
's key for a
match
- if there is a matching key, line 77 returns the result
using the to_sci method from the
Entry class
Line 90 to 98 - Deleting Entries
- line 91 checks to make sure an argument (
name
)
has been given
- line 92 checks if the name given matches a key in
@menagerie
- if the name matches the
delete
method removes
the entry
Line 100 to 102 - Listing Entries
- line 100 specifies that the argument for
cmd_list is called "not_used" - a placeholder
argument name which tells us that the method will not actually
use the argument
- line 101 calls the
dump
method of the
YAML class (see line 6) to show the entire
Menagerie object in YAML format
Line 104 to 133 - Saving to a File
- line 105 to 112: checks if the first character of the
fname
argument is "!"; this sets the
overwrite
variable which determines whether
cmd_save can overwrite an existing file
- line 115 to 117: if
overwrite
is false and the
specified file exists, warn the user with a helpful
message.
- line 118 to 122: if the
fname
argument exists,
set the @fname
instance variable, if not, prompt
the user with a useful error message.
- line 123 to 126 uses ruby's File class to
open the file for writing
- a file descriptor (
fd
) is created on line 124
which is written to in the next line (a YAML dump of our
menagerie)
- line 127 to 131 provides error handling for problems during
the save
Line 135 to 143 - Loading from a File
- line 136 assigns the method's argument to an instance
variable
- line 138 loads the data using the YAML
class's load_data method
- line 139 to 141 provides error handling for problems during
loading
Line 145 to 149 - Showing Help
- prints the $help variable (see line
39)
Line 151 - Starting the Program
- creates a new instance of the Menagerie
class called
obj
Line 153 to 180 - Handling Commands from the User
The program needs a way to handle input from the user. This
section deals with parsing input and splitting it into commands
which call methods in the Menagerie class, and arguments for
those methods.
- line 153 compiles a regular expression into the
cmd_re
variable
- line 154 prints the list of available commands (see line
39)
- line 156 prompts the user for a command
- line 159 captures user input and saves it to the
cmdline
variable
- the if block beginning at line 160 matches the user input
against
cmd_re
- this regular expression captures the first word "(\w+)" and
the word that follows it "(.*)"
- the input is split into two parts:
-
- the first word has the string "cmd_" prepended to it,
and is then assigned to the
cmd
variable
- the second word, or words, are assumed to be arguments
and assigned to the
args
variable
- line 163 checks if
cmd
is a valid method in
the Menagerie class.
-
- if it is, cmd and args are passed to the current
Menagerie object using the send method
(inherited from Ruby's Object class)
- if the command is "quit" the program is ended with a
break
- if neither, an error message is passed to the user
- if the cmd_re regular expression cannot parse the command,
line 177 prints an error message refering the user to the
'help' command
In this step you will run the program and interact with
it.
- To run menagerie.rb without debugging:
Select Debug|Go/Continue. The program
interface displays in the Command Output tab.
Try various commands to test the program.
- In the Command Output tab, enter various commands to test
the program.
- Enter the following commands:
-
- load animals.yaml
- list
- delete Komodo dragon
The output of the last command (including "Error: undefined
method...") indicates that something is not working correctly.
Debugging can help trace this problem. Type quit
in
the Output window before starting the
debugger.
In this step you will add breakpoints to the program and
"debug" it. Adding breakpoints lets you run the program in
sections, making it easier to watch variables and view the output
as it is generated.
Breakpoints are used to identify exactly where a program may
be having problems. A bug has been intentionally left in the
cmd_delete method which can illustrate this.
- Set a breakpoint: On the
menagerie.rb tab, click on the gray margin
immediately to the left of the code on line 93 of the program.
This sets a breakpoint, indicated by a red circle.
- Run the debugger: Select
Debug|Go/Continue (or enter 'F5', or use the
Debug Toolbar). The Debugging
Options dialog box will then pop up; press the
Return key or OK button to
dismiss it. You can pass program options to the program with
the Script Arguments text box, but this
particular program doesn't take any.
- Enter commands: In the Command
Output tab, re-enter the commands from the Running the Program section ('load
animals.yaml', 'list', and 'delete Komodo dragon').
Komodo Tip: Debugger commands can be
accessed from the Debug menu, by shortcut
keys, or from the Debug Toolbar. For a summary of debugger
commands, see the Debugger
Command List.
|
- Watch the debug process: After the last
command, notice that a yellow arrow appears where breakpoint is
set (line 93). This arrow indicates the position at which the
debugger has halted. This tells us that our command did match a
key in
@menagerie
.
- Check the relevant variables: Click on the
Self tab to see the current object's instance
and class variables. Notice the
@menagerie
hash.
Expand the view of the hash by clicking the plus symbol next to
it. It should only contain the "Leopard gecko" entry after the
"Komodo dragon" entry has been deleted.
- Set a Watch variable: Select the
Watch tab of the debugger window, highlight
'
@menagerie.has_key?(name))
' on line 92 and drag
it into the Watch tab. You can place most
valid Ruby expressions in this area, including assignments,
whether they're in the program or not. For example, placing the
expression 'x = 2 + 2
' in the Watch tab will show
that a local variable called 'x' is set to 4.
Komodo Tip: What do the debugger
commands do?
- Step In: Executes the current line
of code and pauses at the following line.
- Step Over: Executes the current line
of code. If the line of code calls a function or method,
the function or method is executed in the background and
the debugger pauses at the line that follows the original
line.
- Step Out: When the debugger is
within a function or method, Step Out executes the code
without stepping through the code line-by-line. The
debugger stops on the line of code following the function
or method call in the calling program.
|
- Step In: Select Debug|Step
In until the debugger stops at line 166 (print
status_message). "Step In" is a debugger command that causes
the debugger to enter a function called from the current
line.
- View local variable: On the
Debug tab, click the Locals
tab. Examine the
status_message
variable. This
variable contains the message that will be returned to the
user.
- Run the debugger: Select
Debug|Go/Continue (or enter 'F5', or use the
Debug Toolbar). The command returns
"
#<Entry:0x83096f8>Error: undefined method `[]' for
#<Entry:0x83096f8>
" which is not a very
user-friendly message. The cmd_delete method
is missing an explicit return
value to provide if
the deletion was successful.
- Fix the problem: On the
Debug menu, click Stop (or
use the Stop button on the Debug Toolbar). Uncomment line 94 by
removing the "#".
- Disable and Delete a breakpoint: Click on
the red breakpoint at line 93. The red breakpoint is now white
with a red outline. This breakpoint is now disabled. Click on
the disabled white breakpoint. This removes the
breakpoint.
- Run the debugger: Select
Debug|Go/Continue and re-run the commands used
previously ('load animals.yaml', 'list', and 'delete Komodo
dragon'). The 'delete' command now returns the message
"Deleted".
Tutorials and Reference Sites
There are many Ruby tutorials and beginner Ruby sites on the
Internet, including: