lib/surrounded/context.rb in surrounded-0.4.1 vs lib/surrounded/context.rb in surrounded-0.5.0
- old
+ new
@@ -14,21 +14,36 @@
end
module Surrounded
module Context
def self.extended(base)
- base.send(:include, InstanceMethods)
+ base.class_eval {
+ @triggers = Set.new
+ @methods_as_triggers = Surrounded::Context.methods_as_triggers
+ include InstanceMethods
+ }
base.singleton_class.send(:alias_method, :setup, :initialize)
end
def self.default_role_type
@default_role_type ||= :module
end
-
- def self.default_role_type=(type)
- @default_role_type = type
+
+ class << self
+ attr_writer :default_role_type, :methods_as_triggers
end
+
+ attr_reader :methods_as_triggers
+
+ def self.methods_as_triggers
+ return @methods_as_triggers if defined?(@methods_as_triggers)
+ @methods_as_triggers = false
+ end
+
+ def set_methods_as_triggers
+ @methods_as_triggers = true
+ end
def new(*args, &block)
instance = allocate
instance.send(:preinitialize)
instance.send(:initialize, *args, &block)
@@ -54,29 +69,17 @@
def default_role_type=(type)
@default_role_type = type
end
- def role(name, type=nil, &block)
- role_type = type || default_role_type
- case role_type
- when :wrap, :wrapper then wrap(name, &block)
- when :interface then interface(name, &block)
- when :module then
- mod_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
- private_const_set(mod_name, Module.new(&block))
- else
- raise InvalidRoleType.new
- end
- end
-
def wrap(name, &block)
require 'delegate'
wrapper_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
klass = private_const_set(wrapper_name, Class.new(SimpleDelegator, &block))
klass.send(:include, Surrounded)
end
+ alias_method :wrapper, :wrap
if module_method_rebinding?
def interface(name, &block)
class_basename = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
interface_name = class_basename + 'Interface'
@@ -87,11 +90,24 @@
define_method(name) do
instance_variable_set("@#{name}", Negotiator.new(role_map.assigned_player(name), behavior))
end
end
end
-
+
+ def role(name, type=nil, &block)
+ role_type = type || default_role_type
+ if role_type == :module
+ mod_name = name.to_s.gsub(/(?:^|_)([a-z])/){ $1.upcase }
+ private_const_set(mod_name, Module.new(&block))
+ else
+ meth = method(role_type)
+ meth.call(name, &block)
+ end
+ rescue NameError => e
+ raise e.extend(InvalidRoleType)
+ end
+
def apply_roles_on(which)
@__apply_role_policy = which
end
def __apply_role_policy
@@ -117,34 +133,53 @@
end
def trigger(name, *args, &block)
store_trigger(name)
- define_method(:"trigger_#{name}", *args, &block)
+ define_method(:"__trigger_#{name}", *args, &block)
- private :"trigger_#{name}"
+ private :"__trigger_#{name}"
- define_method(name, *args){
- begin
- apply_roles if __apply_role_policy == :trigger
-
- self.send("trigger_#{name}", *args)
-
- ensure
- remove_roles if __apply_role_policy == :trigger
- end
- }
+ redo_method(name, args)
end
def store_trigger(name)
- @triggers ||= Set.new
@triggers << name
end
def role_const(name)
if const_defined?(name)
const_get(name)
end
+ end
+
+ def redo_method(name, args)
+ class_eval %{
+ def #{name}(#{args.join(', ')})
+ begin
+ apply_roles if __apply_role_policy == :trigger
+
+ self.send("__trigger_#{name}", #{args.join(', ')})
+
+ ensure
+ remove_roles if __apply_role_policy == :trigger
+ end
+ end
+ }
+ end
+
+ def method_added(name)
+ if methods_as_triggers
+ unless name.to_s.match(/^__trigger|initialize/) || (@triggers && triggers.include?(name))
+ store_trigger(name)
+ args = self.instance_method(name).parameters.map{|p| p.last }
+ alias_method :"__trigger_#{name}", :"#{name}"
+ private :"__trigger_#{name}"
+ remove_method :"#{name}"
+ redo_method(name, args)
+ end
+ end
+ super
end
module InstanceMethods
def role?(name, &block)
return false unless role_map.role?(name)
\ No newline at end of file