Class: DurableDecorator::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/durable_decorator/base.rb

Constant Summary collapse

DEFINITIONS =
{}

Class Method Summary collapse

Class Method Details

.alias_definitions(clazz, method_name, old_sha) ⇒ Object



52
53
54
55
56
57
58
# File 'lib/durable_decorator/base.rb', line 52

def alias_definitions clazz, method_name, old_sha
  clazz.class_eval do
    alias_method("_#{old_sha}_#{method_name}", method_name)
    alias_method("_#{old_sha[0..3]}_#{method_name}", method_name)
    alias_method("_#{old_sha[0..5]}_#{method_name}", method_name)
  end
end

.alias_original(clazz, method_name) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/durable_decorator/base.rb', line 60

def alias_original clazz, method_name
  return unless original_redefinition? clazz, method_name

  clazz.class_eval do
    alias_method("original_#{method_name}", method_name)
  end
end

.definitionsObject



48
49
50
# File 'lib/durable_decorator/base.rb', line 48

def definitions
  DEFINITIONS
end

.determine_arity(target) ⇒ Object



97
98
99
# File 'lib/durable_decorator/base.rb', line 97

def determine_arity target
  extract_method(target).arity
end

.determine_sha(target) ⇒ Object



93
94
95
# File 'lib/durable_decorator/base.rb', line 93

def determine_sha target
  Util.method_sha extract_method(target)
end

.existing_method(clazz, method_name, meta, &block) ⇒ Object

Ensure method exists before creating new definitions



31
32
33
34
35
36
37
38
39
# File 'lib/durable_decorator/base.rb', line 31

def existing_method clazz, method_name, meta, &block
  return if redefined?(clazz, method_name, &block)

  old_method = Validator.validate_existing_definition clazz, method_name
  Validator.validate_method_arity clazz, method_name, old_method, &block
  Validator.validate_decoration_meta clazz, method_name, old_method, meta

  old_method
end

.extract_method(target) ⇒ Object



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/durable_decorator/base.rb', line 101

def extract_method target
  raise "Please provide a fully qualified method name: Module::Clazz#instance_method or .clazz_method" unless target && target.match(/\.|#/)

  class_name, separator, method_name = target.match(/(.*)(\.|#)(.*)/)[1..3]
  clazz = Constantizer.constantize(class_name)
  method = if separator == '#'
    clazz.instance_method(method_name)
  else
    clazz.method(method_name)
  end
end

.original_redefinition?(clazz, method_name) ⇒ Boolean

Returns:

  • (Boolean)


69
70
71
72
# File 'lib/durable_decorator/base.rb', line 69

def original_redefinition? clazz, method_name
  defs = DEFINITIONS[Util.full_method_name(clazz, method_name)]
  !defs || defs.empty?
end

.redefine(clazz, method_name, meta, &block) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/durable_decorator/base.rb', line 12

def redefine clazz, method_name, meta, &block
  if method_name.to_s.match /^self\./
    redefine_instance (class << clazz; self; end), method_name.to_s.gsub("self.",''), meta, &block
  else
    redefine_instance clazz, method_name, meta, &block
  end
end

.redefine_instance(clazz, method_name, meta, &block) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/durable_decorator/base.rb', line 20

def redefine_instance clazz, method_name, meta, &block
  return unless old_method = existing_method(clazz, method_name, meta, &block)

  alias_original clazz, method_name
  alias_definitions clazz, method_name, Util.method_sha(old_method)
  redefine_method clazz, method_name, &block

  store_redefinition clazz, method_name, old_method, block
end

.redefine_method(clazz, method_name, &block) ⇒ Object



42
43
44
45
46
# File 'lib/durable_decorator/base.rb', line 42

def redefine_method clazz, method_name, &block
  clazz.class_eval do
    define_method(method_name.to_sym, &block)
  end
end

.redefined?(clazz, method_name, &block) ⇒ Boolean

Returns:

  • (Boolean)


87
88
89
90
91
# File 'lib/durable_decorator/base.rb', line 87

def redefined? clazz, method_name, &block
  full_name = Util.full_method_name(clazz, method_name)
  redefs = DEFINITIONS[full_name] and
  redefs.include? Util.method_hash(method_name, block)
end

.reset!Object



8
9
10
# File 'lib/durable_decorator/base.rb', line 8

def reset!
  DEFINITIONS.clear
end

.store_redefinition(clazz, name, old_method, new_method) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/durable_decorator/base.rb', line 74

def store_redefinition clazz, name, old_method, new_method
  methods = (DEFINITIONS[Util.full_method_name(clazz, name)] ||= [])
 
  to_store = [new_method]
  to_store.unshift(old_method) if original_redefinition?(clazz, name)
  
  to_store.each do |method|
    methods << Util.method_hash(name, method)
  end

  true
end