class ExtendMethod::Strategy
Attributes
block[R]
has_previous_method_name[R]
method_name[R]
previous_method[R]
previous_method_name[R]
Public Class Methods
new(klass, method_name, block)
click to toggle source
# File lib/extend_method.rb, line 17 def initialize klass, method_name, block @class = klass @method_name = method_name @previous_method_name = :parent_method @has_previous_method_name = :has_parent_method? @block = block begin @previous_method = @class.instance_method(@method_name) rescue NameError => e @previous_method = e end @instance = nil @previous_method_original = nil @has_previous_method_original = nil end
Public Instance Methods
bind!(instance)
click to toggle source
# File lib/extend_method.rb, line 37 def bind! instance @instance = instance end
bound?()
click to toggle source
# File lib/extend_method.rb, line 43 def bound? !@instance.nil? end
execute!()
click to toggle source
# File lib/extend_method.rb, line 120 def execute! strategy = self @class.send(:define_method, method_name) do |*args| strategy.bind! self strategy.save_state! strategy.prepare! return_value = strategy.run! *args strategy.restore_state! strategy.unbind! return_value end end
prepare!()
click to toggle source
# File lib/extend_method.rb, line 101 def prepare! method_name = @method_name previous_method = @previous_method @instance.class.send(:define_method, previous_method_name) do |*args| unless previous_method.is_a? NameError previous_method.bind(self).call(*args) else raise NameError.new "undefined method `previous' in `extend_method' because `#{method_name}' is not previously defined for class `#{self.class.name}'" end end @instance.class.send(:define_method, has_previous_method_name) do |*args| !previous_method.is_a?(NameError) end end
restore_state!()
click to toggle source
# File lib/extend_method.rb, line 81 def restore_state! raise 'Instance state not saved' unless saved_state? @instance.class.send(:remove_method, previous_method_name) @instance.class.send(:define_method, previous_method_name, @previous_method_original) if @previous_method_original @previous_method_original = nil @instance.class.send(:remove_method, has_previous_method_name) @instance.class.send(:define_method, has_previous_method_name, @has_previous_method_original) if @has_previous_method_original @has_previous_method_original = nil end
run!(*args)
click to toggle source
# File lib/extend_method.rb, line 95 def run! *args @instance.instance_exec *args, &block end
save_state!()
click to toggle source
# File lib/extend_method.rb, line 55 def save_state! raise 'Instance state already saved' if saved_state? if @instance.class.method_defined?(previous_method_name) @previous_method_original = @instance.class.send(:instance_method, previous_method_name) else @previous_method_original = false end if @instance.class.method_defined?(has_previous_method_name) @has_previous_method_original = @instance.class.send(:instance_method, has_previous_method_name) else @has_previous_method_original = false end end
saved_state?()
click to toggle source
# File lib/extend_method.rb, line 73 def saved_state? raise 'No bound instance' unless bound? !@previous_method_original.nil? end
unbind!()
click to toggle source
# File lib/extend_method.rb, line 49 def unbind! @instance = nil end