Ad-hoc debugging module

R

Robert Evans

Hi,

I recently found myself playing with a bunch of objects, iterating
their behavior in irb, and I wanted to see just some of the fields
each time I did something instead of the whole object that you would
get with pp or y .

So, I wrote a little module that I could include in interesting
classes, so that I could ask objects things like obj.debug
:)field1, :field5, :field6) instead of printing out all the methods.
Then I got bored doing that and extended it so I could create ad hoc
watch methods, e.g., obj.show_those3:)field1, :field5, :field6).

I thought others might find it useful too. Also, if anyone has any
improvements on it, I am of course interested.

Thanks,
Bob Evans
http://www.junitfactory.com/

module Debuggable
def method_missing(method_name, *args)
method_name = method_name.to_s
if method_name.eql?('debug')
_debug(args)
elsif method_name =~ /^show_/
new_method_name = create_new_watch_method(method_name, args)
self.method(new_method_name).call
elsif method_name =~ /^unshow_/
self.class.class_eval do
watch_name = method_name.slice(method_name.index(/unshow_/)
+ 7, method_name.length)
undef_method "show_#{watch_name}"
end
end
end

def _debug(args)
puts "====="
if args.empty? || args[0].eql?:)all)
puts self.instance_variables.map { |a| "#{a} = #
{self.instance_variable_get(a)}"}.join(", ")
else
strs = args.map do |a|
var = self.instance_variable_get("@#{a}")
if var.nil?
"@#{a} is not an instance variable"
else
"@#{a} = #{var.inspect}"
end
end
puts strs.join(", ")
end
end

def create_new_watch_method(method_name, args)
watch_name = method_name.slice(method_name.index(/show_/) + 5,
method_name.length)
new_method_name = "show_#{watch_name}"
if args.empty?
args = [:all]
end
self.class.class_eval do
define_method(new_method_name) do
_debug(args)
end
end
puts "created permanent watch method: #{new_method_name}"
new_method_name
end
end


===================
given a class
===================

class MyClass
attr_reader :name, :date

def initialize(name, date)
@name = name
@date = date
end
end

===================
loaded in an irb prompt, we can do the following:
===================

%>m = MyClass.new("Bob", Time.now)
%> class MyClass
include Debuggable
end

%>m.debug:)date)
=====
@date = Fri Apr 06 17:15:25 -0700 2007

%> m.debug:)all)
=====
@name = Bob, @date = Fri Apr 06 17:15:25 -0700 2007

%> m.debug
=====
@name = Bob, @date = Fri Apr 06 17:15:25 -0700 2007

%>m.show_date:)date)
created permanent watch method: show_date
=====
@date = Fri Apr 06 17:15:25 -0700 2007

%>m.methods.grep /show/
["show_date"]

%>m.show_date
=====
@date = Fri Apr 06 17:15:25 -0700 2007

%>m.unshow_date
%>m.methods.grep /show/
[]

%>m.show_all
created permanent watch method: show_all
=====
@name = Bob, @date = Fri Apr 06 17:15:25 -0700 2007

%>m.methods.grep /show/
["show_all"]

%>m.show_all
=====
@name = Bob, @date = Fri Apr 06 17:15:25 -0700 2007

%>m.unshow_all
%>m.methods.grep /show/
[]

%>m.show_bazooka
created permanent watch method: show_bazooka
=====
@name = Bob, @date = Fri Apr 06 17:15:25 -0700 2007
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top