# = Module Macros # # A macro construction for creating dynamic mixins. # # == Example # # module Mixin # macro { |options| %{ # def hello # puts 'Hello from #{options[:name]}' # end # } } # end # # class MyClass # include Mixin, :name => 'tml' # end # # m = MyClass.new # m.hello -> 'Hello from tml' # # == Author # # Based on original code by George Moschovitis <gm@navel.gr> # class Module def macro( &blk ) (@macros ||= []) << blk end def macros ; @macros ||= [] ; end alias_method :include_without_macros, :include def include(*args) options = args.last.is_a?(Hash) ? args.pop : {} for mod in args mod.append_dynamic_features( self, options ) end include_without_macros(*args) end # Note: Is this the best name for this callback? def append_dynamic_features( base, options ) macros.each do |m| base.class_eval m.call( options ) end end alias_method :extend_without_macros, :extend def extend(*args) options = args.last.is_a?(Hash) ? args.pop : {} for mod in args mod.extend_dynamic_object( self, options ) end extend_without_macros(*args) end # Note: Is this the best name for this callback? def extend_dynamic_object( base, options ) macros.each do |m| (class << base; self ; end).class_eval m.call( options ) end end end