Skip to content

Instantly share code, notes, and snippets.

@l3x
Created December 5, 2008 04:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save l3x/32234 to your computer and use it in GitHub Desktop.
Save l3x/32234 to your computer and use it in GitHub Desktop.
# What I want is a Rails or Merb plugin that:
#
# * Prints "START" at the start and "END" at the end of each method.
# * That only requires me to enter acts_as_traceable in the class that I want to trace
#
# Output should look something like this:
#
# *** START myclass.mymethod ***
# processing...
# *** myclass.mymethod ***
#
# Currently, I got a class wrapper working using some ruby meta-programming magic (see below)
#
# I ran out of time to research this and would appreciate it if a meta-programming magician could
# pick this up and run with it.
#
# Thanks! - Lex Sheehan
irb(main):167:0* # This is not thread-safe!
irb(main):168:0* class Wrapper
irb(main):169:1>
irb(main):170:1* def initialize(obj)
irb(main):171:2> @obj = obj
irb(main):172:2> @around_filters = []
irb(main):173:2> end
irb(main):174:1>
irb(main):175:1* def method_missing(meth, *args, &block)
irb(main):176:2> puts "in method_missing"
irb(main):177:2> embed(0, meth, *args, &block)
irb(main):178:2> end
irb(main):179:1>
irb(main):180:1* def add_around_filter(proc)
irb(main):181:2> @around_filters.push proc
irb(main):182:2> end
irb(main):183:1>
irb(main):184:1* def remove_around_filter(proc)
irb(main):185:2> @around_filters.delete proc
irb(main):186:2> end
irb(main):187:1>
irb(main):188:1* def embed(filter_num, meth, *args, &block)
irb(main):189:2> if (filter_num >= @around_filters.size)
irb(main):190:3> return @obj.send(meth, *args, &block)
irb(main):191:3> else
irb(main):192:3* return @around_filters.at(filter_num).call(meth, lambda { embed(filter_num + 1, meth, *args, &block) })
irb(main):193:3> end
irb(main):194:2> end
irb(main):195:1>
irb(main):196:1* end # Wrapper
=> nil
irb(main):197:0>
irb(main):198:0* debug_stmts = lambda { |method, proc|
irb(main):199:1* p "*** START " + method.to_s + " ***"
irb(main):200:1> result = proc.call
irb(main):201:1> p "*** END " + method.to_s + " ***"
irb(main):202:1> result
irb(main):203:1> }
=> #<Proc:0x0030fb9c@(irb):198>
irb(main):204:0> class A
irb(main):205:1> def show()
irb(main):206:2> puts "show processing..."
irb(main):207:2> end
irb(main):208:1> end
=> nil
irb(main):209:0> a = A.new
=> #<A:0x410a0>
irb(main):210:0> a.show
show processing...
=> nil
irb(main):211:0> aw = Wrapper.new(A.new)
=> #<Wrapper:0x12d68 @around_filters=[], @obj=#<A:0x12d7c>>
irb(main):212:0> aw.show
in method_missing
show processing...
=> nil
irb(main):213:0> aw.add_around_filter debug_stmts
=> [#<Proc:0x0030fb9c@(irb):198>]
irb(main):214:0> aw.show
in method_missing
"*** START show ***"
show processing...
"*** END show ***"
=> nil
irb(main):215:0>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment