module MooseX module Core def on_init(&block) __moosex__meta.add_role(block) end def after(*methods_name, &block) __moosex__add_hooks(:after, methods_name, block, caller()) end def before(*methods_name, &block) __moosex__add_hooks(:before, methods_name, block, caller()) end def around(*methods_name, &block) __moosex__add_hooks(:around, methods_name, block, caller()) end def requires(*methods) methods.each do |method_name| __moosex__meta.add_requires(method_name) end end def has(attr_name, attr_options = {}) if attr_name.is_a? Array attr_name.each do |attr| __moosex__has(attr, attr_options) end elsif attr_name.is_a? Hash attr_name.each_pair do |attr, options | has(attr, options) end else __moosex__has(attr_name, attr_options) end end private def __moosex__add_hooks(hook, methods_name, block, c) methods_name.each do |method_name| begin __moosex__try_to_add_hook_now(hook, method_name, block) rescue => e MooseX.warn "unable to apply hook #{hook} in #{method_name} @ #{self}: #{e}", c if self.is_a?(Class) __moosex__meta.add_hook(hook, method_name, block) end end end def __moosex__try_to_add_hook_now(hook, method_name, block) case hook when :before __moosex__try_to_add_before_now(method_name, block) when :after __moosex__try_to_add_after_now(method_name, block) when :around __moosex__try_to_add_around_now(method_name, block) end end def __moosex__try_to_add_before_now(method_name, block) method = instance_method method_name define_method method_name do |*args, &proc| block.call(self,*args, &proc) method.bind(self).call(*args, &proc) end end def __moosex__try_to_add_after_now(method_name, block) method = instance_method method_name define_method method_name do |*args, &proc| result = method.bind(self).call(*args, &proc) block.call(self,*args,&proc) result end end def __moosex__try_to_add_around_now(method_name, block) method = instance_method method_name code = Proc.new do | o, *a, &proc| method.bind(o).call(*a,&proc) end define_method method_name do |*args, &proc| block.call(code, self,*args, &proc) end end def __moosex__has(attr_name, attr_options) attr = MooseX::Attribute.new(attr_name, attr_options, self) __moosex__meta.add(attr) __moosex__create_methods(attr) end def __moosex__create_methods(attr) attr.methods.each_pair do |method, block| define_method method do |*args| block.call(self, *args) end end if attr.is.eql?(:rwp) private attr.writter elsif attr.is.eql?(:private) private attr.writter private attr.reader end end end end