class Sqreen::Graft::HookPoint
Constants
- DEFAULT_STRATEGY
Attributes
klass_name[R]
method_kind[R]
method_name[R]
Public Class Methods
new(hook_point, strategy = DEFAULT_STRATEGY)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 41 def initialize(hook_point, strategy = DEFAULT_STRATEGY) @klass_name, @method_kind, @method_name = Sqreen::Graft::HookPoint.parse(hook_point) @strategy = strategy end
parse(hook_point)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 28 def self.parse(hook_point) klass_name, separator, method_name = hook_point.split(/(\#|\.)/, 2) raise ArgumentError, hook_point if klass_name.nil? || separator.nil? || method_name.nil? raise ArgumentError, hook_point unless ['.', '#'].include?(separator) method_kind = separator == '.' ? :klass_method : :instance_method [klass_name.to_sym, method_kind, method_name.to_sym] end
Public Instance Methods
apply(obj, suffix, *args, &block)
click to toggle source
# File lib/sqreen/graft/hook_point.ruby_2.rb, line 11 def apply(obj, suffix, *args, &block) raise 'use super' if super? obj.send("#{method_name}_without_#{suffix}", *args, &block) end
disable(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 156 def disable(key) case @strategy when :chain unchain(key) when :prepend unoverride(key) end end
disabled?(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 165 def disabled?(key) case @strategy when :chain !chained?(key) when :prepend !overridden?(key) end end
enable(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 147 def enable(key) case @strategy when :chain chain(key) when :prepend raise HookPointError, "enable called on prepend mode" end end
exist?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 50 def exist? return false unless Sqreen::Dependency.const_exist?(@klass_name) if klass_method? (klass.singleton_class.public_instance_methods(false) + klass.singleton_class.protected_instance_methods(false) + klass.singleton_class.private_instance_methods(false)).include?(@method_name) elsif instance_method? (klass.public_instance_methods(false) + klass.protected_instance_methods(false) + klass.private_instance_methods(false)).include?(@method_name) else Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" } raise HookPointError, "#{self} unknown hook point kind" end end
install(key, &block)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 108 def install(key, &block) if installed?(key) Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} already installed" } return end unless exist? Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} hook point not found" } return end case @strategy when :chain define(key, &block) chain(key) when :prepend prepend(key) override(key, &block) end end
installed?(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 97 def installed?(key) case @strategy when :chain then defined(key) when :prepend then prepended?(key) && overridden?(key) end end
instance_method?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 93 def instance_method? @method_kind == :instance_method end
klass()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 63 def klass Sqreen::Dependency.resolve_const(@klass_name) end
klass_method?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 67 def klass_method? @method_kind == :klass_method end
private_method?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 71 def private_method? if klass_method? klass.private_methods.include?(@method_name) elsif instance_method? klass.private_instance_methods.include?(@method_name) else Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" } raise HookPointError, "#{self} unknown hook point kind" end end
protected_method?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 82 def protected_method? if klass_method? klass.protected_methods.include?(@method_name) elsif instance_method? klass.protected_instance_methods.include?(@method_name) else Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" } raise HookPointError, "#{self} unknown hook point kind" end end
super?()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 104 def super? @strategy == :prepend end
to_s()
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 46 def to_s @to_s ||= "#{@klass_name}#{@method_kind == :instance_method ? '#' : '.'}#{@method_name}" end
uninstall(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 128 def uninstall(key) unless installed?(key) Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} not installed" } return end unless exist? Sqreen::Graft.logger.debug { "[#{Process.pid}] #{self} hook point not found" } return end case @strategy when :chain disable(key) remove(key) when :prepend unoverride(key) if overridden?(key) end end
Private Instance Methods
chain(suffix)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 307 def chain(suffix) method_name = @method_name if klass_method? klass.singleton_class.instance_eval do alias_method :"#{method_name}_without_#{suffix}", :"#{method_name}" alias_method :"#{method_name}", :"#{method_name}_with_#{suffix}" end elsif instance_method? klass.class_eval do alias_method :"#{method_name}_without_#{suffix}", :"#{method_name}" alias_method :"#{method_name}", :"#{method_name}_with_#{suffix}" end else raise HookPointError, 'unknown hook point kind' end end
chained?(suffix)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 291 def chained?(suffix) method_name = @method_name if klass_method? klass.singleton_class.instance_eval do instance_method(:"#{method_name}").original_name == :"#{method_name}_with_#{suffix}" end elsif instance_method? klass.class_eval do instance_method(:"#{method_name}").original_name == :"#{method_name}_with_#{suffix}" end else raise HookPointError, 'unknown hook point kind' end end
define(suffix, &block)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 242 def define(suffix, &block) hook_point = self method_name = @method_name if klass_method? klass.singleton_class.instance_eval do if hook_point.private_method? private elsif hook_point.protected_method? protected else public end define_method(:"#{method_name}_with_#{suffix}", &block) end elsif instance_method? klass.class_eval do if hook_point.private_method? private elsif hook_point.protected_method? protected else public end define_method(:"#{method_name}_with_#{suffix}", &block) end else raise HookPointError, 'unknown hook point kind' end end
defined(suffix)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 231 def defined(suffix) if klass_method? (klass.methods + klass.protected_methods + klass.private_methods).include?(:"#{method_name}_with_#{suffix}") elsif instance_method? (klass.instance_methods + klass.protected_instance_methods + klass.private_instance_methods).include?(:"#{method_name}_with_#{suffix}") else Sqreen::Graft.logger.error { "[#{Process.pid}] #{self} unknown hook point kind" } raise HookPointError, "#{self} unknown hook point kind" end end
hook_spot(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 176 def hook_spot(key) target = klass_method? ? klass.singleton_class : klass mod = target.ancestors.each { |e| break if e == target; break(e) if e.class == HookSpot && e.key == key } raise "Inconsistency detected: #{target} missing from its own ancestors" if mod.is_a?(Array) [target, mod] end
overridden?(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 198 def overridden?(key) _, mod = hook_spot(key) (mod.instance_methods(false) + mod.protected_instance_methods(false) + mod.private_instance_methods(false)).include?(method_name) end
override(key, &block)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 204 def override(key, &block) hook_point = self method_name = @method_name _, mod = hook_spot(key) mod.instance_eval do if hook_point.private_method? private elsif hook_point.protected_method? protected else public end define_method(:"#{method_name}", &block) end end
prepend(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 184 def prepend(key) target, mod = hook_spot(key) mod ||= HookSpot.new(key) target.instance_eval { prepend(mod) } end
prepended?(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 192 def prepended?(key) _, mod = hook_spot(key) mod != nil end
remove(suffix)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 275 def remove(suffix) method_name = @method_name if klass_method? klass.singleton_class.instance_eval do remove_method(:"#{method_name}_with_#{suffix}") end elsif instance_method? klass.class_eval do remove_method(:"#{method_name}_with_#{suffix}") end else raise HookPointError, 'unknown hook point kind' end end
unchain(suffix)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 325 def unchain(suffix) method_name = @method_name if klass_method? klass.singleton_class.instance_eval do alias_method :"#{method_name}", :"#{method_name}_without_#{suffix}" end elsif instance_method? klass.class_eval do alias_method :"#{method_name}", :"#{method_name}_without_#{suffix}" end end end
unoverride(key)
click to toggle source
# File lib/sqreen/graft/hook_point.rb, line 223 def unoverride(key) method_name = @method_name _, mod = hook_spot(key) mod.instance_eval { remove_method(method_name) } end