lib/surrounded/context.rb in surrounded-0.8.2 vs lib/surrounded/context.rb in surrounded-0.8.3

- old
+ new

@@ -131,11 +131,13 @@ # Define behaviors for your role players 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)) + mod = Module.new(&block) + mod.send(:include, ::Surrounded) + private_const_set(mod_name, mod) else meth = method(role_type) meth.call(name, &block) end rescue NameError => e @@ -160,39 +162,34 @@ # trigger :some_event # def trigger(*names, &block) if block.nil? names.each do |name| - define_trigger_method(name, &block) + convert_method_to_trigger(name) end else name = names.first - - define_method(:"__trigger_#{name}", &block) - - private :"__trigger_#{name}" - store_trigger(name) - - redo_method(name) + define_method(name, &block) + convert_method_to_trigger(name) end end def store_trigger(*names) @triggers.merge(names) end - def define_trigger_method(name, &block) + def convert_method_to_trigger(name) unless triggers.include?(name) || name.nil? alias_method :"__trigger_#{name}", :"#{name}" private :"__trigger_#{name}" remove_method :"#{name}" - redo_method(name) + define_trigger_wrap_method(name) store_trigger(name) end end - def redo_method(name) + def define_trigger_wrap_method(name) class_eval %{ def #{name} begin apply_roles if __apply_role_policy == :trigger @@ -246,10 +243,11 @@ # Check if a given object is a role player in the context. def role_player?(obj) role_map.role_player?(obj) end + # Return a Set of all defined triggers def triggers self.class.triggers end private @@ -267,10 +265,19 @@ end def map_roles(role_object_array) role_object_array.each do |role, object| map_role(role, role_behavior_name(role), object) + + singular_role_name = singularize_name(role) + singular_behavior_name = singularize_name(role_behavior_name(role)) + + if object.respond_to?(:each_with_index) && role_const_defined?(singular_behavior_name) + object.each_with_index do |item, index| + map_role(:"#{singular_role_name}_#{index + 1}", singular_behavior_name, item) + end + end end end def map_role(role, mod_name, object) instance_variable_set("@#{role}", object) @@ -305,18 +312,17 @@ klass.method(wrapper_name).call(obj) end def remove_interface(role, behavior, object) remover_name = (module_removal_methods + unwrap_methods).find{|meth| object.respond_to?(meth) } - return object if !remover_name - object.send(:remove_context) do; end - role_player = object.method(remover_name).call - map_role(role, role_module_basename(behavior), role_player) if behavior + if remover_name + role_player = object.send(remover_name) + end - role_player + return role_player || object end def apply_roles traverse_map method(:add_interface) end @@ -365,9 +371,24 @@ self.class.send(:role_const, name) end def role_const_defined?(name) self.class.const_defined?(name) + end + + def singularize_name(name) + if name.respond_to?(:singularize) + name.singularize + else + # good enough for now but should be updated with better rules + name.to_s.tap do |string| + if string =~ /ies\z/ + string.sub!(/ies\z/,'y') + elsif string =~ /s\z/ + string.sub!(/s\z/,'') + end + end + end end end end end \ No newline at end of file