module Stenotype::Emitter
An extension for a plain Ruby class in order to track invocation of instance methods.
Constants
- ClassMethodsExtension
Class methods for target to be extended by
- InstanceMethodsExtension
Instance methods to be included into target class ancestors chain
Public Class Methods
build_class_methods(class_mod)
click to toggle source
Adds class method [#emit_klass_event_before] to every class
inherited from [Object]
# File lib/stenotype/emitter.rb, line 114 def self.build_class_methods(class_mod) class_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1 def emit_event_before(*methods) proxy = const_get(:InstanceProxy) methods.each do |method| proxy.module_eval do define_method(method) do |*args, **rest_args, &block| Stenotype::Event.emit!( # @todo How do we name such events? "instance_method", { type: "instance_method", class: self.class.name, method: __method__, }, eval_context: { klass: self }, ) super(*args, **rest_args, &block) end end end send(:prepend, proxy) end def emit_klass_event_before(*class_methods) proxy = const_get(:ClassProxy) class_methods.each do |method| proxy.module_eval do define_method(method) do |*args, **rest_args, &block| Stenotype::Event.emit!( # @todo How do we name such events? "class_method", { type: "class_method", class: self.name, method: __method__, }, eval_context: { klass: self }, ) super(*args, **rest_args, &block) end end singleton_class.send(:prepend, proxy) end end RUBY end
build_instance_methods(instance_mod)
click to toggle source
Adds an instance method: [#emit_event] to a target class
where {Stenotype::Emitter} in included in
# File lib/stenotype/emitter.rb, line 93 def self.build_instance_methods(instance_mod) instance_mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1 def emit_event(event_name, attributes = {}, method: caller_locations.first.label, eval_context: nil) Stenotype::Event.emit!( event_name, { type: "instance_method", class: self.class.name, method: method.to_sym, **attributes, }, eval_context: (eval_context || { klass: self }) ) end RUBY end
included(klass)
click to toggle source
@!visibility private
Calls superclass method
# File lib/stenotype/emitter.rb, line 19 def self.included(klass) instance_mod = InstanceMethodsExtension.new class_mod = ClassMethodsExtension.new build_instance_methods(instance_mod) build_class_methods(class_mod) klass.const_set(:InstanceProxy, Module.new) klass.const_set(:ClassProxy, Module.new) klass.public_send(:include, instance_mod) klass.extend(class_mod) super end