module Temple::Mixins::EngineDSL
def element(args, block)
def element(args, block) name = args.shift if Class === name filter = name name = filter.name.to_sym end raise(ArgumentError, 'First argument must be Class or Symbol') unless Symbol === name if block raise(ArgumentError, 'Class and block argument are not allowed at the same time') if filter filter = block end filter ||= args.shift case filter when Proc # 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') unless args.empty? raise(ArgumentError, 'Proc or blocks must have arity 1') unless filter.arity == 1 method_name = "FILTER #{name}" if Class === self define_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)] end when Class # Class argument (e.g Filter class) # The options are passed to the classes constructor. local_options = Hash === args.last ? args.pop : nil raise(ArgumentError, 'Only symbols allowed in option filter') unless args.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') unless filter.respond_to?(:call) [name, filter] end end