1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#!/usr/bin/ruby 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'erb' 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverrequire 'antlr3' 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule ANTLR3 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Template 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule Builder 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver extend ClassMacros 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module ClassMethods 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_writer :template_library 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def template_library 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @template_library ||= ANTLR3::Template::Group.new 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def return_scope_members 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super.push( :template ) 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def load_templates( group_file ) 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @template_library = 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ANTLR3::Template::Group.load( group_file ) 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_template( name, source, &block ) 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver template_library.define_template( name, source, &block ) 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.included( klass ) 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Class === klass and klass.extend( ClassMethods ) 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( input, options = {} ) 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver templates = @templates || options.fetch( :templates ) do 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.class.template_library or ANTLR3::Template::Group.new 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super( input, options ) 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self.templates = templates 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver shared_attribute( :templates ) 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def create_template( source, values = {} ) 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @templates.new( source, values ) 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def fetch_template( name, values = {} ) 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @templates.fetch( name, values ) 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvermodule RewriteBuilder 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include Builder 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.included( klass ) 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Class === klass and klass.extend( Builder::ClassMethods ) 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def cast_input( input, options ) 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case input 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when TokenSource then TokenRewriteStream.new( input, options ) 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when IO, String 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if lexer_class = self.class.associated_lexer 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver TokenRewriteStream.new( lexer_class.new( input, options ), options ) 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise ArgumentError, Util.tidy( <<-END, true ) 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | unable to automatically convert input #{ input.inspect } 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | to a ANTLR3::TokenStream object as #{ self.class } 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver | does not appear to have an associated lexer class 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverautoload :GroupFile, 'antlr3/template/group-file' 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Group < Module 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver autoload :Lexer, 'antlr3/template/group-file' 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver autoload :Parser, 'antlr3/template/group-file' 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.parse( source, options = {} ) 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver namespace = options.fetch( :namespace, ::Object ) 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lexer = Lexer.new( source, options ) 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser = Parser.new( lexer, options ) 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( parser.group( namespace ) ) 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.load( group_file, options = {} ) 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver unless( File.file?( group_file ) ) 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dir = $LOAD_PATH.find do | d | 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver File.file?( File.join( dir, group_file ) ) 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end or raise( LoadError, "no such template group file to load %s" % group_file ) 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver group_file = File.join( dir, group_file ) 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver namespace = options.fetch( :namespace, ::Object ) 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver input = ANTLR3::FileStream.new( group_file, options ) 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver lexer = Lexer.new( input, options ) 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver parser = Parser.new( lexer, options ) 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( parser.group( namespace ) ) 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.new( &block ) 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super do 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver const_set( :TEMPLATES, {} ) 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and module_eval( &block ) 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def new( source, values = {} ) 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver erb = ERB.new( source, nil, '%' ) 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver template = Context.new( values ) 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver template.extend( self ) 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver sclass = class << template; self; end 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver erb.def_method( sclass, 'to_s' ) 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( template ) 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def fetch( name, values = {} ) 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self::TEMPLATES.fetch( name.to_s ).new( values ) 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def templates 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self::TEMPLATES 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def template_defined?( name ) 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self::TEMPLATES.has_key?( name.to_s ) 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_template( name, source, parameters = nil, &block ) 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = name.to_s.dup.freeze 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Context.define( self, name, parameters ) do | tclass | 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self::TEMPLATES[ name ] = tclass 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ERB.new( source, nil, '%' ).def_method( tclass, 'to_s' ) 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver define_template_methods( tclass ) 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def alias_template( new_name, old_name ) 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new_name, old_name = new_name.to_s.dup.freeze, old_name.to_s 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver context = self::TEMPLATES.fetch( old_name.to_s ) do 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise( NameError, 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "undefined template `%s' for template group %p" % [ old_name, self ] 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ) 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver context.define_alias( new_name ) do | tclass | 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self::TEMPLATES[ new_name ] = tclass 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver define_template_methods( tclass ) 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_template_methods( context ) 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = context.name 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if params = context.parameters 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver init = params.names.map do | param | 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "___[ #{ param.inspect } ] = #{ param }" 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end.join( "\n" ) 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_eval( <<-END ) 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_function 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ name }( #{ params } ) 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver TEMPLATES[ #{ name.inspect } ].new do | ___ | 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #{ init } 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ name }!( #{ params } ) 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver TEMPLATES[ #{ name.inspect } ].new do | ___ | 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver #{ init } 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end.to_s 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_eval( <<-END ) 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver module_function 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ name }( values = {} ) 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver TEMPLATES[ #{ name.inspect } ].new( values ) 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def #{ name }!( values = {} ) 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver TEMPLATES[ #{ name.inspect } ].new( values ).to_s 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver END 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Context 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver VARIABLE_FORM = /^(@)?[a-z_\x80-\xff][\w\x80-\xff]*$/ 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SETTER_FORM = /^([a-z_\x80-\xff][\w\x80-\xff]*)=$/ 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ATTR_FORM = /^[a-z_\x80-\xff][\w\x80-\xff]*$/ 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver class << self 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :group, :name, :parameters 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected :group=, :name= 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define_alias( name ) 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new = clone 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new.name = name 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new.group = @group 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( new ) 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( new ) 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def define( group, name, parameters ) 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Class.new( self ) do 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver include( group ) 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @group = group 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @name = name 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @parameters = parameters 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( self ) 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def method_missing( method, *args ) 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case name = method.to_s 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when SETTER_FORM then return( self[ $1 ] = args.first ) 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when ATTR_FORM 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver args.empty? and has_ivar?( name ) and return( self[ name ] ) 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def []=( name, value ) 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instance_variable_set( make_ivar( name ), value ) 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def []( name ) 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = make_ivar( name ) 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instance_variable_defined?( name ) ? instance_variable_get( name ) : nil 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def <<( variable_map ) 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver variable_map.each_pair do | name, value | 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver self[ name ] = value 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def initialize( variable_map = nil ) 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver variable_map and self << variable_map 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( self ) 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverprivate 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def has_ivar?( name ) 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver instance_variable_defined?( make_ivar( name ) ) 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def make_ivar( name ) 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver name = name.to_s 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver VARIABLE_FORM =~ name or 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver raise ArgumentError, "cannot convert %p to an instance variable name" % name 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver $1 ? name : "@#{ name }" 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 286324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverParameter = Struct.new( :name, :default ) 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass Parameter 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_s 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver default ? "#{ name } = #{ default }" : "#{ name }" 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverclass ParameterList < ::Array 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver attr_accessor :splat, :block 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def self.default 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver new.add( :values ) do | p | 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver p.default = '{}' 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def names 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver names = map { | param | param.name.to_s } 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @splat and names << @splat.to_s 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @block and names << @block.to_s 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( names ) 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def add( name, options = nil ) 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver param = 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver case name 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver when Parameter then name 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else Parameter.new( name.to_s ) 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if options 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver default = options[ :default ] and param.default = default 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver param.splat = options.fetch( :splat, false ) 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver param.block = options.fetch( :block, false ) 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver block_given? and yield( param ) 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver push( param ) 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( self ) 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver def to_s 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver signature = join( ', ' ) 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @splat and signature << ", *" << @splat.to_s 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @block and signature << ", &" << @block.to_s 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return( signature ) 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver end 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverend 334