lib/forward_referencing.rb in eymiha_util-0.1.3 vs lib/forward_referencing.rb in eymiha_util-0.1.4

- old
+ new

@@ -22,40 +22,47 @@ end # To be called when a section of code that could contain a forward reference # is entered. The method returns a newly created ForwardReference with the # given dependency that can be jumped to during resolution. - def create_forward_reference dependency=nil - forward_reference = ForwardReference.new dependency + def create_forward_reference(dependency=nil,context=nil) + forward_reference = ForwardReference.new(dependency,context) @forward_references << forward_reference forward_reference end # To be called when a section of code that could contain a forward reference # has successfully been reached. It is used to remove the ForwardReference # that was created at the start of the section, and asserts that a # resolution was made. - def remove_forward_reference forward_reference=nil + def remove_forward_reference(forward_reference=nil) @forward_references.delete forward_reference if (forward_reference.kind_of? ForwardReference) @had_forward_reference_resolution = true end # To be called to try to resolve any unresolved ForwardReferences by jumping # to each in turn and retrying the code that caused it. This method repeats # until nothing more is resolved. At that point unresolved forward reference # may still exist, to be possibly resolved by another call to this method - # downstream. + # downstream. Prior to continuing to a forward reference, the + # establish_forward_reference context method is called with the context that + # was provided at the time the forward reference was created to give the + # receiver a chance to reset any transcient infromation. def resolve_forward_references forward_references = @forward_references @forward_references = [] @had_forward_reference_resolution = false if forward_references.size > 0 @forward_reference_resolver ||= callcc {|cont| cont} while (@forward_reference_resolver == nil) forward_reference = forward_references.shift - forward_reference.continuation.call if forward_reference != nil + if forward_reference != nil + establish_forward_reference_context(forward_reference.context) if + respond_to?(:establish_forward_reference_context,true) + forward_reference.continuation.call + end end @forward_reference_resolver = nil resolve_forward_references if @had_forward_reference_resolution end @@ -63,11 +70,11 @@ # reference, it will continue during normal processing and jump back to the # resolve_forward_references method during resolution. def continue_forward_reference_resolution @forward_reference_resolver.call if @forward_reference_resolver end - + # Returns a hash of dependencies to arrays of the ForwardReferences that # have them as dependencies. def forward_reference_dependencies dependencies = {} @forward_references.each { |forward_reference| @@ -121,14 +128,20 @@ # Holds an arbitrary object that indicates why the forward reference # occurred. attr_accessor :dependency - # Returns a new instance with a valid continuation and the given dependency. - def initialize(dependency) + # Holds an arbitrary object that holds context that can be re-established + # to help resolve the forward reference. + attr_accessor :context + + # Returns a new instance with a valid continuation, the given dependency + # and contextual information. + def initialize(dependency=nil,context=nil) @continuation = nil @continuation = callcc{|cont| cont} while (@continuation == nil) @dependency = dependency + @context = context end # Returns a string indicating the current state of the ForwardReference. def to_s "#{self_name} dependency #{dependency} #{continuation}"