I need debugging tips?


#1

Hi all,

Like most other frameworks, Ruby groups code by Model/View/Controller
instead
of by task, and therefore I’m having a hard time debugging a problem
from the
Agile Rails book where looping through @items errors out because one or
more
items is nil.

I managed to empty the cart by placing session[:cart] = nil in
find_cart() in
the store_controller_rb, and the problem continued after I removed that
diagnostic, thereby proving it wasn’t caused just a bad record that got
in
there. I’ve examined the dump screen produced by the error every way but
loose and can’t find anything that helps. I went back and looked at
everything I did recently – nothing obvious. I looked at
log/production.log,
and saw an error pointing to code I didn’t write (Rails code, in other
words).

I’d like to place diagnostic prints in the controller code to see if I’m
placing nil records in the @items whatever, but where would such
diagnostic
prints print out?

So I need some debugging tips. What are your favorite Rails debugging
techniques?

Thanks

SteveT

Steve L.
Author:


#2

I like to use breakpoints in the code and invoke script/breakpointer. It
drops me into irb and ALL the environment vars of the controller are
available. You can ctrl-D to continue and if your breakpoint() is in a
loop
you will hit it each time and see the vars changing.

-bakki kudva

On 1/6/06, Steve L. removed_email_address@domain.invalid wrote:


#3

On Jan 6, 2006, at 1:56 PM, Steve L. wrote:

I managed to empty the cart by placing session[:cart] = nil in
and saw an error pointing to code I didn’t write (Rails code, in other

Thanks

SteveT

Steve-

One good way to debug nil errors in your views is to use the debug

method. So if your looping over @items try this at the top of your view:

<%= debig(@items) %>

You will get a pretty printed yaml version of your object and all

the data it holds. And another way to avoid the nil errors inside of
a loop is to do something like this:

<% @items.each do |item| -%>

<%= item.name rescue nil -%>


<%= item.info rescue nil -%>


<% end -%>
The rescue nil deal will just print an empty string instead of

making your whole page error out with a nil error when item.whatever
is nil inside the loop. Hope that helps a bit.

Cheers-
-Ezra Z.
Yakima Herald-Republic
WebMaster
http://yakimaherald.com
509-577-7732
removed_email_address@domain.invalid


#4

On Friday 06 January 2006 05:04 pm, Bakki K. wrote:

I like to use breakpoints in the code and invoke script/breakpointer. It
drops me into irb and ALL the environment vars of the controller are
available. You can ctrl-D to continue and if your breakpoint() is in a loop
you will hit it each time and see the vars changing.

-bakki kudva

Sounds good Bakki,

How do I set a breakpoint?

Thanks

SteveT


#5

No-one’s mentioned logging yet.

In a controller, you can write this:

logger.info "My Stuff: #(@items.inspect)"

And this output shows up in the log/development.log file.

The logging functionality is more important to me than the IRB solution,
as
I can leave it in the code and check the log output if I seem something
break.

More info here:
http://wiki.rubyonrails.com/rails/pages/HowtoConfigureLogging
http://wiki.rubyonrails.com/rails/pages/logger


#6

On Friday 06 January 2006 06:19 pm, Tom F. wrote:

break.

More info here:
http://wiki.rubyonrails.com/rails/pages/HowtoConfigureLogging
http://wiki.rubyonrails.com/rails/pages/logger

Oh Oh,

undefined local variable or method `logger’ for #Cart:0x407f5e2c

This happened before and after I added the following to the bottom of
config/environment.rb:

begin
RAILS_DEFAULT_LOGGER =
Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
rescue StandardError
RAILS_DEFAULT_LOGGER = Logger.new(STDERR)
RAILS_DEFAULT_LOGGER.level = Logger::WARN
RAILS_DEFAULT_LOGGER.warn(
"Rails Error: Unable to access log file. Please ensure that
log/#{RAILS_ENV}.log exists and is chmod 0666. " +
“The log level has been raised to WARN and the output directed to
STDERR
until the problem is fixed.”
)
end
[ActiveRecord, ActionController, ActionMailer].each { |mod|
mod::Base.logger
||= RAILS_DEFAULT_LOGGER }


#7

On Friday 06 January 2006 05:10 pm, Ezra Z. wrote:

Steve-

One good way to debug nil errors in your views is to use the debug
method. So if your looping over @items try this at the top of your view:

<%= debig(@items) %>

You will get a pretty printed yaml version of your object and all
the data it holds.

I tried that and didn’t see any nils, unless the dash at the bottom,
with
nothing after it, indicates a nil. Does that lone dash indicate a nil?

Thanks

Steve


#8

On Jan 6, 2006, at 3:46 PM, Steve L. wrote:

You will get a pretty printed yaml version of your object and all
the data it holds.

I tried that and didn’t see any nils, unless the dash at the
bottom, with
nothing after it, indicates a nil. Does that lone dash indicate a nil?

Thanks

Steve

I think it does, but could you paste the debug yaml dump here and I
can tell you?

Cheers-
-Ezra Z.
WebMaster
Yakima Herald-Republic Newspaper
removed_email_address@domain.invalid
509-577-7732


#9

The logger variable is part of your controller. Your original question
was:

“I’d like to place diagnostic prints in the controller code to see if
I’m
placing nil records in the @items whatever, but where would such
diagnostic
prints print out?”

So, this will work:
class MyController < ApplicationController
def some_action
logger.info “My Cart Is: #{@cart.inspect}”
end
end

But your current problem is that you are trying to log from a Model
object
that is not derived from the ActiveRecord::Base class. In that case you
have to do use the RAILS_DEFAULT_LOGGER global constant:

class Cart
def something
RAILS_DEFAULT_LOGGER.info “My Cart Is: #{self.inspect}”
end
end

If you are using Rails 1.0, the code you added to environment.rb is not
necessary, it is built into Rails.


#10

Just insert breakpoint() in your ruby code which you want to examine.
Invoke script/breakpointer and you should see…
No connection to breakpoint service at
druby://localhost:42531(DRb::DRbConnError)
Tries to connect will be made every 2 seconds…
Don’t worry about the ‘No connection at breakpoint’ bit. Carry on with
your
app and when the breakpoint hits you will see something like:
Executing break point at
./script/…/config/…/app/controllers/my_controller.rb:16 in `new’
irb(#MyController:0x4079fef0):001:0>
Which means you are in irb. Now you can simply type in variable names
and
look at their values.
The best documentation I found for the breakpointer is in its source
file
which is at:
/usr/lib/ruby/gems/1.8/gems/activesupport-1.2.5/lib/active_support/breakpoint.rb
on my Debian system.

hope it helps,

bakki


#11

How does one single step through the code? I have tried irb and it
doenst
allow me to do that!