Class: DurableDecorator::Base

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

Constant Summary collapse

REDEFINITIONS =
{}

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("#{method_name}_#{old_sha}", method_name)
    alias_method("#{method_name}_#{old_sha[0..3]}", method_name)
    alias_method("#{method_name}_#{old_sha[0..5]}", 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("#{method_name}_original", method_name)
  end
end

.determine_sha(target) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/durable_decorator/base.rb', line 97

def determine_sha 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

  Util.method_sha(method)
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

.original_redefinition?(clazz, method_name) ⇒ Boolean

Returns:

  • (Boolean)


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

def original_redefinition? clazz, method_name
  !REDEFINITIONS[Util.full_method_name(clazz, method_name)]
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)


86
87
88
89
90
91
92
93
94
95
# File 'lib/durable_decorator/base.rb', line 86

def redefined? clazz, method_name, &block
  begin
    result =
      overrides = REDEFINITIONS[clazz][method_name] and
      overrides.select{|o| o == Util.method_hash(method_name)}.first and
      true
  rescue
    false
  end
end

.redefinitionsObject



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

def redefinitions
  REDEFINITIONS
end

.reset!Object



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

def reset!
  REDEFINITIONS.clear
end

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



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

def store_redefinition clazz, name, old_method, new_method
  methods = REDEFINITIONS[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