Class: Sqreen::Graft::HookPoint

Inherits:
Object
  • Object
show all
Defined in:
lib/sqreen/graft/hook_point.rb,
lib/sqreen/graft/hook_point.ruby_2.rb,
lib/sqreen/graft/hook_point.ruby_3.rb

Constant Summary collapse

DEFAULT_STRATEGY =
Module.respond_to?(:prepend) ? :prepend : :chain

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hook_point, strategy = DEFAULT_STRATEGY) ⇒ HookPoint

Returns a new instance of HookPoint.



41
42
43
44
# 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

Instance Attribute Details

#klass_nameObject (readonly)

Returns the value of attribute klass_name.



39
40
41
# File 'lib/sqreen/graft/hook_point.rb', line 39

def klass_name
  @klass_name
end

#method_kindObject (readonly)

Returns the value of attribute method_kind.



39
40
41
# File 'lib/sqreen/graft/hook_point.rb', line 39

def method_kind
  @method_kind
end

#method_nameObject (readonly)

Returns the value of attribute method_name.



39
40
41
# File 'lib/sqreen/graft/hook_point.rb', line 39

def method_name
  @method_name
end

Class Method Details

.parse(hook_point) ⇒ Object

Raises:

  • (ArgumentError)


28
29
30
31
32
33
34
35
36
37
# 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

Instance Method Details

#apply(obj, suffix, *args, **kwargs, &block) ⇒ Object



11
12
13
14
15
# 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) ⇒ Object



156
157
158
159
160
161
162
163
# 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) ⇒ Boolean

Returns:

  • (Boolean)


165
166
167
168
169
170
171
172
# 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) ⇒ Object



147
148
149
150
151
152
153
154
# 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?Boolean

Returns:

  • (Boolean)


50
51
52
53
54
55
56
57
58
59
60
61
# 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) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# 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) ⇒ Boolean

Returns:

  • (Boolean)


97
98
99
100
101
102
# 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?Boolean

Returns:

  • (Boolean)


93
94
95
# File 'lib/sqreen/graft/hook_point.rb', line 93

def instance_method?
  @method_kind == :instance_method
end

#klassObject



63
64
65
# File 'lib/sqreen/graft/hook_point.rb', line 63

def klass
  Sqreen::Dependency.resolve_const(@klass_name)
end

#klass_method?Boolean

Returns:

  • (Boolean)


67
68
69
# File 'lib/sqreen/graft/hook_point.rb', line 67

def klass_method?
  @method_kind == :klass_method
end

#private_method?Boolean

Returns:

  • (Boolean)


71
72
73
74
75
76
77
78
79
80
# 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?Boolean

Returns:

  • (Boolean)


82
83
84
85
86
87
88
89
90
91
# 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?Boolean

Returns:

  • (Boolean)


104
105
106
# File 'lib/sqreen/graft/hook_point.rb', line 104

def super?
  @strategy == :prepend
end

#to_sObject



46
47
48
# 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) ⇒ Object



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# 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