moduleTemplemoduleMixins# @api privatemoduleEngineDSLdefchain_modified!enddefappend(*args,&block)chain<<element(args,block)chain_modified!enddefprepend(*args,&block)chain.unshift(element(args,block))chain_modified!enddefremove(name)found=falsechain.reject!do|i|equal=i.first==namefound=trueifequalequalendraise"#{name} not found"unlessfoundchain_modified!endaliasuseappenddefbefore(name,*args,&block)name=Class===name?name.name.to_sym:nameraise(ArgumentError,'First argument must be Class or Symbol')unlessSymbol===namee=element(args,block)found,i=false,0whilei<chain.sizeifchain[i].first==namefound=truechain.insert(i,e)i+=2elsei+=1endendraise"#{name} not found"unlessfoundchain_modified!enddefafter(name,*args,&block)name=Class===name?name.name.to_sym:nameraise(ArgumentError,'First argument must be Class or Symbol')unlessSymbol===namee=element(args,block)found,i=false,0whilei<chain.sizeifchain[i].first==namefound=truei+=1chain.insert(i,e)endi+=1endraise"#{name} not found"unlessfoundchain_modified!enddefreplace(name,*args,&block)name=Class===name?name.name.to_sym:nameraise(ArgumentError,'First argument must be Class or Symbol')unlessSymbol===namee=element(args,block)found=falsechain.each_with_indexdo|c,i|ifc.first==namefound=truechain[i]=eendendraise"#{name} not found"unlessfoundchain_modified!enddeffilter(name,*options,&block)use(name,Temple::Filters.const_get(name),*options,&block)enddefgenerator(name,*options,&block)use(name,Temple::Generators.const_get(name),*options,&block)endprivatedefelement(args,block)name=args.shiftifClass===namefilter=namename=filter.name.to_symendraise(ArgumentError,'First argument must be Class or Symbol')unlessSymbol===nameifblockraise(ArgumentError,'Class and block argument are not allowed at the same time')iffilterfilter=blockendfilter||=args.shiftcasefilterwhenProc# Proc or block argument# The proc is converted to a method of the engine class.# The proc can then access the option hash of the engine.raise(ArgumentError,'Too many arguments')unlessargs.empty?raise(ArgumentError,'Proc or blocks must have arity 1')unlessfilter.arity==1method_name="FILTER #{name}"ifClass===selfdefine_method(method_name,&filter)[name,instance_method(method_name)]else(class<<self;self;end).class_eval{define_method(method_name,&filter)}[name,method(method_name)]endwhenClass# Class argument (e.g Filter class)# The options are passed to the classes constructor.local_options=Hash===args.last?args.pop:nilraise(ArgumentError,'Only symbols allowed in option filter')unlessargs.all?{|o|Symbol===o}[name,filter,args,local_options]else# Other callable argument (e.g. Object of class which implements #call or Method)# The callable has no access to the option hash of the engine.raise(ArgumentError,'Class or callable argument is required')unlessfilter.respond_to?(:call)[name,filter]endendendendend