lib/surrounded/context/negotiator.rb in surrounded-0.9.5 vs lib/surrounded/context/negotiator.rb in surrounded-0.9.6

- old
+ new

@@ -5,53 +5,65 @@ # Return a class which has methods defined to forward the method to # the wrapped object delegating to the behavior module. # This prevents hits to method_missing. def for_role(mod) klass = Class.new(self) + # Define access to the provided module + klass.send(:define_method, :__behaviors__) do + mod + end + # For each method in the module, directly forward to the wrapped object to + # circumvent method_missing mod.instance_methods(false).each do |meth| num = __LINE__; klass.class_eval %{ def #{meth}(*args, &block) - @behaviors.instance_method(:#{meth}).bind(@object).call(*args, &block) + __behaviors__.instance_method(:#{meth}).bind(@object).call(*args, &block) end }, __FILE__, num end - klass.send(:define_method, :__behaviors__) do - mod - end klass end end identity = %w[__send__ object_id equal?] method_access = %w[respond_to? method __behaviors__] reserved_methods = (identity + method_access).join('|') - # Remove all methods except the identity methods + # Remove all methods except the reserved methods instance_methods.reject{ |m| m.to_s =~ /#{reserved_methods}/ }.each do |meth| undef_method meth end + include Surrounded + private + # Store the context in the wrapped object if it can do so + def store_context(&block) + if @object.respond_to?(__method__, true) + @object.send(__method__, &block) + else + super + end + self + end + # These only differ in the message they send + alias remove_context store_context + def initialize(object) - @object, @behaviors = object, __behaviors__ + @object = object end def method_missing(meth, *args, &block) @object.send(meth, *args, &block) end def respond_to_missing?(meth, include_private=false) @object.respond_to?(meth, include_private) end end - - # The method_missing definition from Surrounded will apply - # before the one defined above. This allows the methods for - # the objects in the context to work properly - Negotiator.send(:prepend, Surrounded) end end \ No newline at end of file