• First and foremost, run your scripts with warnings enabled (the-W command-line
Option ).
• If you happen to forget a "," in an argument list-especially to print-you can
Produce some very odd error messages.
• A parse error at the last line of the source often indicates a missing end keyword,
Sometimes quite a bit earlier.
• An Attribute setter is not being called. Within a class de fi nition, Ruby will parse
Setter = as an assignment to a local variable, not as a method call. Use the form
Self. setter = to indicate the method call.
Class incorrect
Attr_accessor: one,: Two
Def initialize
One = 1 # incorrect-sets local variable
Self. Two = 2
End
End
OBJ = incorrect. New
OBJ. One → Nil
OBJ. Two → 2
• Objects that don't appear to be properly set up may have been victims of an incor-
Rectly spelled initialize method.
Class incorrect
Attr_reader: Answer
Def initialise # <spelling error
@ Answer = 42
End
End
Ultimate = incorrect. New
Ultimate. Answer → Nil
The same kind of thing can happen if you misspell the instance variable name.
Class incorrect
Attr_reader: Answer
Def initialize
@ Ansible = 42 # <«spelling error
End
End
Ultimate = incorrect. New
Ultimate. Answer → Nil
• Block parameters are in the same scope as local variables. If an existing local
Variable with the same name as a block parameter exists when the block executes,
That variable will be Modi already ed by the call to the block. This may or may not be
Good thing.
C = "Carbon"
I = "Iodine"
Elements = [C, I]
Elements. each_with_index do | element, I |
# Do some chemistry
End
C → "Carbon"
I → 1
• Watch out for precedence issues, especially when using {} Instead of do/end.
Def one (ARG)
If block_given?
"Block given to 'one' returns # {yield }"
Else
ARG
End
End
Def two
If block_given?
"Block given to 'two' returns # {yield }"
End
End
Result1 = one two {
"Three"
}
Result2 = one two do
"Three"
End
Puts "with braces, result =#{ result1 }"
Puts "with do/end, result =#{ result2 }"
Produces:
With braces, result = block given to 'two' returns three
With do/end, result = block given to 'one' returns three
• Output written to a terminal may be buffered. This means you may not see a mes-
Sage you write immediately. In addition, if you write messages to both $ stdout
And $ stderr, the output may not appear in the order you were expecting. Always
Use nonbuffered I/O (set sync = true) for debug messages.
• If numbers don't come out right, perhaps they're strings. text read from a role le will
Be a string and will not be automatically converted to a number by ruby. A call
To integer will work wonders (and will throw an exception if the input isn't
Well-formed integer). A common mistake Perl programmers make is
While line = gets
Num1, num2 = line. Split (/,/)
#...
End
You can rewrite this
While line = gets
Num1, num2 = line. Split (/,/)
Num1 = INTEGER (num1)
Num2 = INTEGER (num2)
#...
End
Or, you cocould convert all the strings using map.
While line = gets
Num1, num2 = line. Split (/,/). Map {| Val | INTEGER (VAL )}
#...
End
• Unintended aliasing-if you are using an object as the key of a hash, make sure it
Doesn' t change its hash value (or arrange to call hash # rehash if it does ).
Arr = [1, 2]
Hash = {arr => "value "}
Hash [arr] → "value"
Arr [0] = 99
Hash [arr] Nil
→
Hash. rehash {[99, 2] => "value "}
→
Hash [arr] "value"
→
• Make sure the class of the object you are using is what you think it is. If in doubt,
Use puts my_obj.class.
• Make sure your method names start with a lowercase letter and class and constant
Names start with an uppercase letter.
• If method callaren't doing what you 'd like CT, make sure you 've ve put parentheses
Around the arguments.
• Make sure the open parenthesis of a method's parameter list butts up against
End of the method name with no intervening spaces.
• Use IRB and the debugger.
• Use object # freeze. If you suspect that some unknown portion of code is setting
A variable to a bogus value, try freezing the variable. The Culprit will then be
Caught during the attempt to modify the variable.