Class: Context

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

Constant Summary collapse

@@default =
nil
@@stack =
Array.new

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeContext

Returns a new instance of Context.



18
19
20
21
# File 'lib/cop.rb', line 18

def initialize
  @count = 0
  @adaptations = Array.new
end

Class Attribute Details

.stackObject



32
33
34
# File 'lib/cop.rb', line 32

def self.stack
  @@stack
end

Instance Attribute Details

#adaptationsObject

Returns the value of attribute adaptations.



16
17
18
# File 'lib/cop.rb', line 16

def adaptations
  @adaptations
end

#managerObject



86
87
88
89
90
91
92
# File 'lib/cop.rb', line 86

def manager
  return @manager unless @manager.nil?
  return @manager = Context.default.manager unless self == Context.default
  @manager = ContextManager.new
  self.name= "default"
  @manager
end

Class Method Details

.default(*args) ⇒ Object



23
24
25
26
27
28
29
30
# File 'lib/cop.rb', line 23

def self.default(*args)
  return @@default = args.first unless args.size == 0
  if @@default.nil?
    @@default = self.new
    @@default.activate
  end
  @@default
end

.named(name) ⇒ Object



36
37
38
39
40
# File 'lib/cop.rb', line 36

def self.named(name)
  c = self.new
  c.name= name
  c
end

.proceedObject

Raises:

  • (Exception)


42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/cop.rb', line 42

def self.proceed
  ca = @@stack.last
  raise Exception, "proceed should only be called from adapted methods" if ca.nil?
  adaptations = self.default.manager.adaptations.select do |adaptation|
    adaptation.adapts_class? ca.adapted_class, ca.adapted_selector
  end
  raise Exception, "no adaptation found" if adaptations.empty?
  meth = @@default.manager.adaptation_chain(ca.adapted_class, ca.adapted_selector)[1].adapted_implementation
  if meth.is_a? Proc
    meth.call(meth.parameters)
  else
    meth.bind(ca.adapted_class.class_eval("self.new")).call(meth.parameters)
  end
end

Instance Method Details

#activateObject



61
62
63
64
65
66
# File 'lib/cop.rb', line 61

def activate
  self.manager.signal_activation_request(self)
  self.activate_adaptations if @count == 0
  @count += 1
  self
end

#activate_adaptationsObject



148
149
150
151
152
153
154
155
156
157
# File 'lib/cop.rb', line 148

def activate_adaptations
  @adaptations.each do |adaptation|
    begin
      self.manager.activate_adaptation(adaptation)
	rescue Exception
 self.rollback_adaptations
 raise Exception, $!
    end
  end
end

#activation_ageObject



57
58
59
# File 'lib/cop.rb', line 57

def activation_age
  self.manager.context_activation_age(self)
end

#active?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/cop.rb', line 74

def active?
  @count > 0
end

#adapt_class(a_class, a_selector, a_method) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/cop.rb', line 106

def adapt_class(a_class, a_selector, a_method)
  begin
    method = a_class.instance_method(a_selector)
    rescue NameError
      raise Exception, "can't adapt inexistent method #{a_selector.to_s} in #{a_method.to_s}"
  end
  default = ContextAdaptation.in_context(Context.default, a_class, a_selector, method)
  Context.default.add_adaptation(default) { :preserve }
  adaptation = ContextAdaptation.in_context(self, a_class, a_selector, a_method)
  self.add_adaptation(adaptation) { raise Exception, "an adaptation already exists for #{self.to_s}" }
end

#add_adaptation(context_adaptation, &block) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/cop.rb', line 118

def add_adaptation(context_adaptation, &block)
  existing = @adaptations.index do |adaptation|
    adaptation.same_target? context_adaptation
  end
  if existing.nil?
    self.add_inexistent_adaptation(context_adaptation)
    return self
  end
  existing = @adaptations[existing]
  action = yield
  if action == :overwrite
    self.remove_existing_adaptation(existing)
    self.add_inexistent_adaptation(context_adaptation)
  else
    raise Exception, "unknown overriding action #{action.to_s}" unless action == :preserve
  end
end

#add_inexistent_adaptation(context_adaptation) ⇒ Object

Raises:

  • (Exception)


136
137
138
139
140
# File 'lib/cop.rb', line 136

def add_inexistent_adaptation(context_adaptation)
  raise Exception, "can't add foreign adaptation" unless self == context_adaptation.context
  @adaptations.push(context_adaptation)
  self.manager.activate_adaptation(context_adaptation) if self.active?
end

#deactivateObject



68
69
70
71
72
# File 'lib/cop.rb', line 68

def deactivate
  self.deactivate_adaptations if @count == 1
  @count -= 1 unless @count == 0
  self
end

#deactivate_adaptationsObject



159
160
161
162
163
# File 'lib/cop.rb', line 159

def deactivate_adaptations
  @adaptations.each do |adaptation|
    self.manager.deactivate_adaptation(adaptation)
  end
end

#discardObject



94
95
96
97
98
99
100
# File 'lib/cop.rb', line 94

def discard
  self.manager.discard_context(self)
  Context.default(nil) if self == Context.default
  @adaptations.each do |adaptation|
    self.remove_existing_adaptation(adaptation)
  end
end

#nameObject



78
79
80
# File 'lib/cop.rb', line 78

def name
  self.manager.directory[self]
end

#name=(new_name) ⇒ Object



82
83
84
# File 'lib/cop.rb', line 82

def name=(new_name)
  new_name.nil? ? self.manager.directory.delete(self) : self.manager.directory[self] = new_name
end

#remove_existing_adaptation(context_adaptation) ⇒ Object

Raises:

  • (Exception)


142
143
144
145
146
# File 'lib/cop.rb', line 142

def remove_existing_adaptation(context_adaptation)
  raise Exception, "can't remove foreign adaptation" unless self == context_adaptation.context
  self.manager.deactivate_adaptation(context_adaptation) if self.active?
  raise Exception, "can't remove adaptation" if @adaptations.delete(context_adaptation).nil?
end

#rollback_adaptationsObject



165
166
167
168
169
170
171
172
# File 'lib/cop.rb', line 165

def rollback_adaptations
  deployed = self.manager.adaptations.select do |adaptation|
    adaptation.context == self
  end
  deployed.each do |adaptation|
    self.manager.deactivate_adaptation(adaptation)
  end
end

#to_sObject



102
103
104
# File 'lib/cop.rb', line 102

def to_s
  (self.name.nil? ? "anonymous" : "#{self.name}") + " context"
end