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