lib/surrounded/context/negotiator.rb in surrounded-0.9.1 vs lib/surrounded/context/negotiator.rb in surrounded-0.9.2
- old
+ new
@@ -1,30 +1,51 @@
module Surrounded
module Context
class Negotiator
+ class << self
+ # 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)
+ 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)
+ end
+ }, __FILE__, num
+ end
+ klass
+ end
+ end
+
+
identity = "__send__|object_id"
- instance_methods.each do |meth|
- unless meth.to_s =~ /#{identity}/
- undef_method meth
- end
+ # Remove all methods except the identity methods
+ instance_methods.reject{ |m|
+ m.to_s =~ /#{identity}/
+ }.each do |meth|
+ undef_method meth
end
private
def initialize(object, behaviors)
@object, @behaviors = object, behaviors
end
def method_missing(meth, *args, &block)
- if @behaviors.instance_methods.include?(meth)
- the_method = @behaviors.instance_method(meth)
- the_method.bind(@object).call(*args, &block)
- else
- @object.send(meth, *args, &block)
- end
+ @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