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