lib/bumbler/hooks.rb in bumbler-0.7.0 vs lib/bumbler/hooks.rb in bumbler-0.8.0

- old
+ new

@@ -3,47 +3,78 @@ module Hooks @slow_threshold = 100.0 @started_items = {} @slow_requires = {} - module RequireLogger - def require(path, *args) - ::Bumbler::Hooks.handle_require(path) { super } - end - end - # Everything's a class method (we're a singleton) class << self attr_writer :slow_threshold attr_reader :slow_requires # Inject our custom handling of require into the Kernel. def hook_require! - @hooking_require = true + hook_instance_require! + hook_singleton_require! + end - # There are two independent require methods. Joy! - ::Kernel.prepend RequireLogger - (class << ::Kernel; self; end).prepend RequireLogger + def hook_instance_require! + @hooking_instance_require = true - @hooking_require = nil + ::Kernel.module_eval do + orig_instance_require = instance_method(:require) + define_method(:require) do |path, *args| + ::Bumbler::Hooks.handle_require(path) do + orig_instance_require.bind(self).call(path, *args) + end + end + private :require # rubocop:disable Style/AccessModifierDeclarations + end + + @hooking_instance_require = nil end + def hook_singleton_require! + @hooking_singleton_require = true + + ::Kernel.module_eval do + class << self + orig_public_require = Kernel.public_method(:require) + define_method(:require) do |path, *args| + ::Bumbler::Hooks.handle_require(path) do + orig_public_require.call(path, *args) + end + end + end + end + + @hooking_singleton_require = nil + end + # Even better: Other gems hook require as well. The instance method one at least. def watch_require! ::Kernel.module_eval do # It isn't previously defined in Kernel. This could be a bit dangerous, though. def self.method_added(method_name, *_args) - if method_name == :require && !::Bumbler::Hooks.hooking_require? - # Fix those hooks. - ::Bumbler::Hooks.hook_require! + if method_name == :require && !Bumbler::Hooks.hooking_instance_require? + ::Bumbler::Hooks.hook_instance_require! end end + + def self.singleton_method_added(method_name, *_args) + if method_name == :require && !Bumbler::Hooks.hooking_singleton_require? + ::Bumbler::Hooks.hook_singleton_require! + end + end end end - def hooking_require? - @hooking_require + def hooking_instance_require? + @hooking_instance_require + end + + def hooking_singleton_require? + @hooking_singleton_require end # Actually do something about a require here. def handle_require(path, &block) # break out early if we're already handling the path