Class: Hometown::CreationTracer
- Inherits:
-
Object
- Object
- Hometown::CreationTracer
- Defined in:
- lib/hometown/creation_tracer.rb
Constant Summary collapse
- HOMETOWN_TRACE_ON_INSTANCE =
:@__hometown_creation_backtrace
Instance Method Summary collapse
- #add_trace_for(instance) ⇒ Object
- #find_trace_for(instance) ⇒ Object
-
#initialize ⇒ CreationTracer
constructor
A new instance of CreationTracer.
- #install_traced_new(clazz) ⇒ Object
- #on_creation_add_trace_for_instance(clazz) ⇒ Object
- #patch(clazz, other_instance_hook = nil) ⇒ Object
- #patched?(clazz) ⇒ Boolean
- #remember_patched(clazz) ⇒ Object
- #scrubbed_caller ⇒ Object
-
#update_on_instance_created(clazz, on_instance_created) ⇒ Object
This hook allows other tracing in Hometown to get a whack at an object after it’s been created without forcing them to patch new themselves.
Constructor Details
#initialize ⇒ CreationTracer
Returns a new instance of CreationTracer.
3 4 5 |
# File 'lib/hometown/creation_tracer.rb', line 3 def initialize @tracing_classes = {} end |
Instance Method Details
#add_trace_for(instance) ⇒ Object
48 49 50 51 |
# File 'lib/hometown/creation_tracer.rb', line 48 def add_trace_for(instance) trace = Hometown::Trace.new(instance.class, scrubbed_caller) instance.instance_variable_set(HOMETOWN_TRACE_ON_INSTANCE, trace) end |
#find_trace_for(instance) ⇒ Object
58 59 60 |
# File 'lib/hometown/creation_tracer.rb', line 58 def find_trace_for(instance) instance.instance_variable_get(HOMETOWN_TRACE_ON_INSTANCE) end |
#install_traced_new(clazz) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/hometown/creation_tracer.rb', line 31 def install_traced_new(clazz) clazz.instance_eval do class << self def new_traced(*args, &blk) instance = new_untraced(*args, &blk) self.instance_hooks.each { |hook| hook.call(instance) } instance end alias_method :new_untraced, :new alias_method :new, :new_traced end end end |
#on_creation_add_trace_for_instance(clazz) ⇒ Object
27 28 29 |
# File 'lib/hometown/creation_tracer.rb', line 27 def on_creation_add_trace_for_instance(clazz) update_on_instance_created(clazz, method(:add_trace_for)) end |
#patch(clazz, other_instance_hook = nil) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/hometown/creation_tracer.rb', line 7 def patch(clazz, other_instance_hook=nil) if !patched?(clazz) remember_patched(clazz) on_creation_add_trace_for_instance(clazz) install_traced_new(clazz) end # Critical that we only add other instance hooks after our primary # creation hook is registered above! update_on_instance_created(clazz, other_instance_hook) end |
#patched?(clazz) ⇒ Boolean
19 20 21 |
# File 'lib/hometown/creation_tracer.rb', line 19 def patched?(clazz) @tracing_classes.include?(clazz) end |
#remember_patched(clazz) ⇒ Object
23 24 25 |
# File 'lib/hometown/creation_tracer.rb', line 23 def remember_patched(clazz) @tracing_classes[clazz] = true end |
#scrubbed_caller ⇒ Object
53 54 55 56 |
# File 'lib/hometown/creation_tracer.rb', line 53 def scrubbed_caller backtrace = caller.dup backtrace.reject { |line| %r{/lib/hometown/creation_tracer.rb}.match(line) } end |
#update_on_instance_created(clazz, on_instance_created) ⇒ Object
This hook allows other tracing in Hometown to get a whack at an object after it’s been created without forcing them to patch new themselves
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/hometown/creation_tracer.rb', line 64 def update_on_instance_created(clazz, on_instance_created) return unless on_instance_created clazz.instance_eval do def instance_hooks hooks = (self.ancestors + [self]).map do |target| target.instance_variable_get(:@instance_hooks) end hooks.flatten! hooks.compact! hooks.uniq! hooks end @instance_hooks ||= [] @instance_hooks << on_instance_created end end |