parseargs 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/lib/parseargs-0.2.0.rb +452 -0
  2. data/lib/parseargs.rb +452 -0
  3. metadata +40 -0
@@ -0,0 +1,452 @@
1
+ unless defined? $__parseargs__
2
+ module ParseArgs
3
+ #--{{{
4
+ ParseArgs::LIBDIR = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR unless
5
+ defined? ParseArgs::LIBDIR
6
+
7
+ ParseArgs::VERSION = '0.1.0' unless
8
+ defined? ParseArgs::VERSION
9
+
10
+ require 'enumerator'
11
+ require 'ostruct'
12
+
13
+ class ArgumentNotGiven < StandardError; end
14
+ class KeywordNotGiven < StandardError; end
15
+
16
+ module Util
17
+ #--{{{
18
+ module Methods
19
+ #--{{{
20
+ def get_kw kw, table = nil, ret = nil
21
+ #--{{{
22
+ k = kw
23
+ table ||= self if Hash === self
24
+ return table[k] if table.has_key? k
25
+ k = "#{ k }"
26
+ return table[k] if table.has_key? k
27
+ k = k.intern
28
+ return table[k] if table.has_key? k
29
+ ret ||= (default if Hash === self)
30
+ return ret
31
+ #--}}}
32
+ end
33
+ def has_kw kw, table = nil
34
+ #--{{{
35
+ k = kw
36
+ table ||= self if Hash === self
37
+ return true if table.has_key? k
38
+ k = "#{ k }"
39
+ return true if table.has_key? k
40
+ k = k.intern
41
+ return true if table.has_key? k
42
+ return false
43
+ #--}}}
44
+ end
45
+ alias has_kw? has_kw
46
+ #--}}}
47
+ end
48
+ def self::append_features klass
49
+ #--{{{
50
+ klass.extend Methods
51
+ klass.class_eval{ include Methods }
52
+ #--}}}
53
+ end
54
+ #--}}}
55
+ end
56
+
57
+ class Parser
58
+ #--{{{
59
+ include Util
60
+
61
+ class Argument
62
+ #--{{{
63
+ include Util
64
+
65
+ attr 'name', true
66
+ attr 'required', true
67
+ alias required? required
68
+ attr 'default', true
69
+ attr 'type', true
70
+ attr 'ducktype', true
71
+ attr 'coerce', true
72
+ attr 'convince', true
73
+ attr 'validate', true
74
+
75
+ def initialize name, opts = {}
76
+ #--{{{
77
+ @name = name
78
+ @required = get_kw 'required', opts
79
+ @default = get_kw 'default', opts
80
+ @types = get_kw('type', opts, get_kw('types', opts, []))
81
+ @ducktypes = get_kw('ducktype', opts, get_kw('ducktypes', opts, []))
82
+ @coerce = get_kw 'coerce', opts
83
+ @convince = get_kw 'convince', opts
84
+ @validate = get_kw 'validate', opts
85
+ @types = [ @types ].flatten
86
+ @ducktypes = [ @ducktypes ].flatten
87
+ if @coerce and (String === @coerce or Symbol === @coerce)
88
+ msg = @coerce.dup
89
+ @coerce = lambda{|obj| obj.send msg}
90
+ end
91
+ if @convince and Module === @convince
92
+ mod = @convince
93
+ @convince = lambda{|obj| obj.extend mod}
94
+ end
95
+ if @validate and not Proc === @validate
96
+ equiv = @validate.dup
97
+ @validate = lambda{|obj| equiv === obj}
98
+ end
99
+ @value_set = false
100
+ #--}}}
101
+ end
102
+ def value= v
103
+ #--{{{
104
+ unless @types.empty?
105
+ ok = false
106
+ @types.each{|t| if v.is_a? t; ok = true; break; end}
107
+ if not ok and @coerce
108
+ v = @coerce[v]
109
+ ok = false
110
+ @types.each{|t| if v.is_a? t; ok = true; break; end}
111
+ end
112
+ raise TypeError, "value given not of type(#{ @types.join ',' }) in '#{ @name }='" unless ok
113
+ end
114
+ unless @ducktypes.empty?
115
+ ok = true
116
+ @ducktypes.each{|t| unless v.respond_to? t;ok = false; break; end}
117
+ if not ok and @convince
118
+ @convince[v]
119
+ ok = true
120
+ @ducktypes.each{|t| unless v.respond_to? t; ok = false; break; end}
121
+ end
122
+ if not ok and @coerce
123
+ v = @coerce[v]
124
+ ok = true
125
+ @ducktypes.each{|t| unless v.respond_to? t; ok = false; break; end}
126
+ end
127
+ raise TypeError, "value given not of ducktype(#{ @ducktypes.join ',' }) in '#{ @name }='" unless ok
128
+ end
129
+ if @validate
130
+ valid = @validate[v]
131
+ unless valid
132
+ vmsg = v.inspect
133
+ vmsg = vmsg[0,16] << '...' if vmsg.size > 16
134
+ raise ArgumentError, "invalid value(#{ vmsg }) given in '#{ @name }='"
135
+ end
136
+ end
137
+ @value = v
138
+ @value_set = true
139
+ @value
140
+ #--}}}
141
+ end
142
+ def value
143
+ #--{{{
144
+ if @value_set
145
+ @value
146
+ else
147
+ @default
148
+ end
149
+ #--}}}
150
+ end
151
+ def optional
152
+ #--{{{
153
+ not required
154
+ #--}}}
155
+ end
156
+ alias optional? optional
157
+ #--}}}
158
+ end # class Argument
159
+
160
+ class Keyword < Argument
161
+ #--{{{
162
+ #--}}}
163
+ end # class Keyword
164
+
165
+ attr :receiver, true
166
+ def initialize(opts = {}, &b)
167
+ #--{{{
168
+ @required_arguments = []
169
+ @optional_arguments = []
170
+ @required_keywords = []
171
+ @optional_keywords = []
172
+ opts.each{|k,v| send k, v}
173
+ instance_eval &b
174
+ #--}}}
175
+ end
176
+ def define_arguments(list, required, *descs)
177
+ #--{{{
178
+ unless descs.empty?
179
+ metadata = descs.size >= 2 && Hash === descs.last ? descs.pop : {}
180
+ descs.flatten!
181
+ mdefault ||= get_kw('default', metadata)
182
+ descs.each do |desc|
183
+ names, default = Hash === desc ? desc.to_a.first : [desc, mdefault]
184
+ req = default ? false : required
185
+ names = [ names ] unless names.respond_to? :each
186
+ names.each do |name|
187
+ list << Argument::new(name, metadata.merge('required'=>req,'default'=>default))
188
+ end
189
+ end
190
+ end
191
+ list
192
+ #--}}}
193
+ end
194
+ def required_arguments(*descs)
195
+ #--{{{
196
+ if descs.empty?
197
+ @required_arguments
198
+ else
199
+ define_arguments(@required_arguments, true, *descs)
200
+ end
201
+ #--}}}
202
+ end
203
+ alias required_argument required_arguments
204
+ alias req_arguments required_arguments
205
+ alias req_argument required_arguments
206
+ alias req_args required_arguments
207
+ alias req_arg required_arguments
208
+ alias r_args required_arguments
209
+ alias r_arg required_arguments
210
+ alias args required_arguments
211
+ alias arg required_arguments
212
+ alias arguments required_arguments
213
+ alias argument required_arguments
214
+ alias ras required_arguments
215
+ alias ra required_arguments
216
+ def optional_arguments(*descs)
217
+ #--{{{
218
+ if descs.empty?
219
+ @optional_arguments
220
+ else
221
+ define_arguments(@optional_arguments, false, *descs)
222
+ end
223
+ #--}}}
224
+ end
225
+ alias optional_argument optional_arguments
226
+ alias opt_arguments optional_arguments
227
+ alias opt_argument optional_arguments
228
+ alias opt_args optional_arguments
229
+ alias opt_arg optional_arguments
230
+ alias o_args optional_arguments
231
+ alias o_arg optional_arguments
232
+ alias oas optional_arguments
233
+ alias oa optional_arguments
234
+ def define_keywords(list, required, *descs)
235
+ #--{{{
236
+ unless descs.empty?
237
+ metadata = descs.size >= 2 && Hash === descs.last ? descs.pop : {}
238
+ descs.flatten!
239
+ mdefault ||= get_kw('default', metadata)
240
+ descs.each do |desc|
241
+ names, default = Hash === desc ? desc.to_a.first : [desc, mdefault]
242
+ req = default ? false : required
243
+ names = [ names ] unless names.respond_to? :each
244
+ names.each do |name|
245
+ list << Keyword::new(name, metadata.merge('required'=>req,'default'=>default))
246
+ end
247
+ end
248
+ end
249
+ list
250
+ #--}}}
251
+ end
252
+ def required_keywords(*descs)
253
+ #--{{{
254
+ if descs.empty?
255
+ @required_keywords
256
+ else
257
+ define_keywords(@required_keywords, true, *descs)
258
+ end
259
+ #--}}}
260
+ end
261
+ alias required_keyword required_keywords
262
+ alias req_keywords required_keywords
263
+ alias req_keyword required_keywords
264
+ alias req_kws required_keywords
265
+ alias req_kw required_keywords
266
+ alias r_kws required_keywords
267
+ alias r_kw required_keywords
268
+ alias kws required_keywords
269
+ alias kw required_keywords
270
+ alias keywords required_keywords
271
+ alias keyword required_keywords
272
+ def optional_keywords(*descs)
273
+ #--{{{
274
+ if descs.empty?
275
+ @required_keywords
276
+ else
277
+ define_keywords(@optional_keywords, false, *descs)
278
+ end
279
+ #--}}}
280
+ end
281
+ alias optional_keyword optional_keywords
282
+ alias opt_keywords optional_keywords
283
+ alias opt_keyword optional_keywords
284
+ alias opt_kws optional_keywords
285
+ alias opt_kw optional_keywords
286
+ alias o_kws optional_keywords
287
+ alias o_kw optional_keywords
288
+ alias okws optional_keywords
289
+ alias okw optional_keywords
290
+ #
291
+ # TODO - thinks about *args signature??
292
+ #
293
+ def parse arg
294
+ #--{{{
295
+ enumerable, receiver =
296
+ if Hash === arg
297
+ a = arg.to_a
298
+ pair = a.shift
299
+ unless a.empty?
300
+ raise ArgumentError, "wrong number of arguments(#{ a.size + 1 } for 1"
301
+ end
302
+ pair
303
+ else
304
+ [arg, Receiver::new]
305
+ end
306
+
307
+ p_args = enumerable.to_enum.map
308
+
309
+ n = p_args.size
310
+
311
+ @required_arguments.each do |arg|
312
+ if p_args.empty?
313
+ raise ArgumentNotGiven, "<#{ arg.name }>"
314
+ end
315
+ p_arg = p_args.shift
316
+ arg.value = p_arg
317
+ receiver_set receiver, arg.name, arg.value
318
+ end
319
+
320
+ @optional_arguments.each do |arg|
321
+ p_arg = p_args.empty? ? arg.default : p_args.shift
322
+ arg.value = p_arg
323
+ receiver_set receiver, arg.name, arg.value
324
+ end
325
+
326
+ if receiver.respond_to? "arguments="
327
+ receiver.arguments = @required_arguments + @optional_arguments
328
+ end
329
+
330
+ p_kws = Hash === p_args.first ? p_args.shift : {}
331
+
332
+ @required_keywords.each do |kw|
333
+ p_kw, p_arg = extract_kw kw, p_kws
334
+ raise KeywordNotGiven, "<#{ kw.name }>" if p_kw.nil?
335
+ kw.value = p_arg
336
+ receiver_set receiver, kw.name, kw.value
337
+ end
338
+
339
+ @optional_keywords.each do |kw|
340
+ p_kw, p_arg = extract_kw kw, p_kws
341
+ p_arg = p_kw ? p_arg : kw.default
342
+ kw.value = p_arg
343
+ receiver_set receiver, kw.name, kw.value
344
+ end
345
+
346
+ if receiver.respond_to? "keywords="
347
+ receiver.keywords = @required_keywords + @optional_keywords
348
+ end
349
+
350
+ unless p_args.empty?
351
+ raise ArgumentError, "wrong number of arguments(#{ n } for #{ n - p_args.size })"
352
+ end
353
+
354
+ receiver
355
+ #--}}}
356
+ end
357
+ def extract_kw kw, kws
358
+ #--{{{
359
+ k = kw.name
360
+ return [k, kws[k]] if kws.has_key? k
361
+ k = "#{ k }"
362
+ return [k, kws[k]] if kws.has_key? k
363
+ k = k.intern
364
+ return [k, kws[k]] if kws.has_key? k
365
+ return [nil, nil]
366
+ #--}}}
367
+ end
368
+ def receiver_set receiver, name, value
369
+ #--{{{
370
+ begin
371
+ receiver.send "[]=", name, value
372
+ rescue NameError
373
+ begin
374
+ receiver.send "#{ name }=", value
375
+ rescue NameError
376
+ receiver.send "#{ name }", value
377
+ end
378
+ end
379
+ #--}}}
380
+ end
381
+ #--}}}
382
+ end # class Parser
383
+
384
+ class Receiver < ::Hash
385
+ #--{{{
386
+ include Util
387
+ attr_accessor 'arguments'
388
+ alias_method 'args', 'arguments'
389
+ attr_accessor 'keywords'
390
+ alias_method 'kws', 'keywords'
391
+ def method_missing(m, *a, &b)
392
+ #--{{{
393
+ return(get_kw(m)) if has_kw? m
394
+ super
395
+ #--}}}
396
+ end
397
+ #--}}}
398
+ end
399
+
400
+ module ModuleMethods
401
+ #--{{{
402
+ def parseargs(*____argv, &____block)
403
+ #--{{{
404
+ ::ParseArgs::parseargs(*____argv, &____block)
405
+ #--}}}
406
+ end
407
+ #--}}}
408
+ end # module ModuleMethods
409
+
410
+ module InstanceMethods
411
+ #--{{{
412
+ def parseargs(*____argv, &____block)
413
+ #--{{{
414
+ ::ParseArgs::parseargs(*____argv, &____block)
415
+ #--}}}
416
+ end
417
+ #--}}}
418
+ end # module InstanceMethods
419
+
420
+ class << self
421
+ #--{{{
422
+ def append_features klass
423
+ #--{{{
424
+ klass.extend ModuleMethods
425
+ klass.class_eval{ include InstanceMethods }
426
+ #--}}}
427
+ end
428
+ def parseargs(*____argv, &____block)
429
+ #--{{{
430
+ parser = ParseArgs::Parser::new(&____block)
431
+ receiver = parser.parse(*____argv)
432
+ receiver.freeze
433
+ receiver
434
+ #--}}}
435
+ end
436
+ #--}}}
437
+ end
438
+
439
+ #--}}}
440
+ end # module ParseArgs
441
+
442
+ class Object
443
+ #--{{{
444
+ def ParseArgs(*a, &b)
445
+ #--{{{
446
+ ::ParseArgs::parseargs(*a, &b)
447
+ #--}}}
448
+ end
449
+ #--}}}
450
+ end
451
+ $__parseargs__ = __FILE__
452
+ end
@@ -0,0 +1,452 @@
1
+ unless defined? $__parseargs__
2
+ module ParseArgs
3
+ #--{{{
4
+ ParseArgs::LIBDIR = File::dirname(File::expand_path(__FILE__)) + File::SEPARATOR unless
5
+ defined? ParseArgs::LIBDIR
6
+
7
+ ParseArgs::VERSION = '0.1.0' unless
8
+ defined? ParseArgs::VERSION
9
+
10
+ require 'enumerator'
11
+ require 'ostruct'
12
+
13
+ class ArgumentNotGiven < StandardError; end
14
+ class KeywordNotGiven < StandardError; end
15
+
16
+ module Util
17
+ #--{{{
18
+ module Methods
19
+ #--{{{
20
+ def get_kw kw, table = nil, ret = nil
21
+ #--{{{
22
+ k = kw
23
+ table ||= self if Hash === self
24
+ return table[k] if table.has_key? k
25
+ k = "#{ k }"
26
+ return table[k] if table.has_key? k
27
+ k = k.intern
28
+ return table[k] if table.has_key? k
29
+ ret ||= (default if Hash === self)
30
+ return ret
31
+ #--}}}
32
+ end
33
+ def has_kw kw, table = nil
34
+ #--{{{
35
+ k = kw
36
+ table ||= self if Hash === self
37
+ return true if table.has_key? k
38
+ k = "#{ k }"
39
+ return true if table.has_key? k
40
+ k = k.intern
41
+ return true if table.has_key? k
42
+ return false
43
+ #--}}}
44
+ end
45
+ alias has_kw? has_kw
46
+ #--}}}
47
+ end
48
+ def self::append_features klass
49
+ #--{{{
50
+ klass.extend Methods
51
+ klass.class_eval{ include Methods }
52
+ #--}}}
53
+ end
54
+ #--}}}
55
+ end
56
+
57
+ class Parser
58
+ #--{{{
59
+ include Util
60
+
61
+ class Argument
62
+ #--{{{
63
+ include Util
64
+
65
+ attr 'name', true
66
+ attr 'required', true
67
+ alias required? required
68
+ attr 'default', true
69
+ attr 'type', true
70
+ attr 'ducktype', true
71
+ attr 'coerce', true
72
+ attr 'convince', true
73
+ attr 'validate', true
74
+
75
+ def initialize name, opts = {}
76
+ #--{{{
77
+ @name = name
78
+ @required = get_kw 'required', opts
79
+ @default = get_kw 'default', opts
80
+ @types = get_kw('type', opts, get_kw('types', opts, []))
81
+ @ducktypes = get_kw('ducktype', opts, get_kw('ducktypes', opts, []))
82
+ @coerce = get_kw 'coerce', opts
83
+ @convince = get_kw 'convince', opts
84
+ @validate = get_kw 'validate', opts
85
+ @types = [ @types ].flatten
86
+ @ducktypes = [ @ducktypes ].flatten
87
+ if @coerce and (String === @coerce or Symbol === @coerce)
88
+ msg = @coerce.dup
89
+ @coerce = lambda{|obj| obj.send msg}
90
+ end
91
+ if @convince and Module === @convince
92
+ mod = @convince
93
+ @convince = lambda{|obj| obj.extend mod}
94
+ end
95
+ if @validate and not Proc === @validate
96
+ equiv = @validate.dup
97
+ @validate = lambda{|obj| equiv === obj}
98
+ end
99
+ @value_set = false
100
+ #--}}}
101
+ end
102
+ def value= v
103
+ #--{{{
104
+ unless @types.empty?
105
+ ok = false
106
+ @types.each{|t| if v.is_a? t; ok = true; break; end}
107
+ if not ok and @coerce
108
+ v = @coerce[v]
109
+ ok = false
110
+ @types.each{|t| if v.is_a? t; ok = true; break; end}
111
+ end
112
+ raise TypeError, "value given not of type(#{ @types.join ',' }) in '#{ @name }='" unless ok
113
+ end
114
+ unless @ducktypes.empty?
115
+ ok = true
116
+ @ducktypes.each{|t| unless v.respond_to? t;ok = false; break; end}
117
+ if not ok and @convince
118
+ @convince[v]
119
+ ok = true
120
+ @ducktypes.each{|t| unless v.respond_to? t; ok = false; break; end}
121
+ end
122
+ if not ok and @coerce
123
+ v = @coerce[v]
124
+ ok = true
125
+ @ducktypes.each{|t| unless v.respond_to? t; ok = false; break; end}
126
+ end
127
+ raise TypeError, "value given not of ducktype(#{ @ducktypes.join ',' }) in '#{ @name }='" unless ok
128
+ end
129
+ if @validate
130
+ valid = @validate[v]
131
+ unless valid
132
+ vmsg = v.inspect
133
+ vmsg = vmsg[0,16] << '...' if vmsg.size > 16
134
+ raise ArgumentError, "invalid value(#{ vmsg }) given in '#{ @name }='"
135
+ end
136
+ end
137
+ @value = v
138
+ @value_set = true
139
+ @value
140
+ #--}}}
141
+ end
142
+ def value
143
+ #--{{{
144
+ if @value_set
145
+ @value
146
+ else
147
+ @default
148
+ end
149
+ #--}}}
150
+ end
151
+ def optional
152
+ #--{{{
153
+ not required
154
+ #--}}}
155
+ end
156
+ alias optional? optional
157
+ #--}}}
158
+ end # class Argument
159
+
160
+ class Keyword < Argument
161
+ #--{{{
162
+ #--}}}
163
+ end # class Keyword
164
+
165
+ attr :receiver, true
166
+ def initialize(opts = {}, &b)
167
+ #--{{{
168
+ @required_arguments = []
169
+ @optional_arguments = []
170
+ @required_keywords = []
171
+ @optional_keywords = []
172
+ opts.each{|k,v| send k, v}
173
+ instance_eval &b
174
+ #--}}}
175
+ end
176
+ def define_arguments(list, required, *descs)
177
+ #--{{{
178
+ unless descs.empty?
179
+ metadata = descs.size >= 2 && Hash === descs.last ? descs.pop : {}
180
+ descs.flatten!
181
+ mdefault ||= get_kw('default', metadata)
182
+ descs.each do |desc|
183
+ names, default = Hash === desc ? desc.to_a.first : [desc, mdefault]
184
+ req = default ? false : required
185
+ names = [ names ] unless names.respond_to? :each
186
+ names.each do |name|
187
+ list << Argument::new(name, metadata.merge('required'=>req,'default'=>default))
188
+ end
189
+ end
190
+ end
191
+ list
192
+ #--}}}
193
+ end
194
+ def required_arguments(*descs)
195
+ #--{{{
196
+ if descs.empty?
197
+ @required_arguments
198
+ else
199
+ define_arguments(@required_arguments, true, *descs)
200
+ end
201
+ #--}}}
202
+ end
203
+ alias required_argument required_arguments
204
+ alias req_arguments required_arguments
205
+ alias req_argument required_arguments
206
+ alias req_args required_arguments
207
+ alias req_arg required_arguments
208
+ alias r_args required_arguments
209
+ alias r_arg required_arguments
210
+ alias args required_arguments
211
+ alias arg required_arguments
212
+ alias arguments required_arguments
213
+ alias argument required_arguments
214
+ alias ras required_arguments
215
+ alias ra required_arguments
216
+ def optional_arguments(*descs)
217
+ #--{{{
218
+ if descs.empty?
219
+ @optional_arguments
220
+ else
221
+ define_arguments(@optional_arguments, false, *descs)
222
+ end
223
+ #--}}}
224
+ end
225
+ alias optional_argument optional_arguments
226
+ alias opt_arguments optional_arguments
227
+ alias opt_argument optional_arguments
228
+ alias opt_args optional_arguments
229
+ alias opt_arg optional_arguments
230
+ alias o_args optional_arguments
231
+ alias o_arg optional_arguments
232
+ alias oas optional_arguments
233
+ alias oa optional_arguments
234
+ def define_keywords(list, required, *descs)
235
+ #--{{{
236
+ unless descs.empty?
237
+ metadata = descs.size >= 2 && Hash === descs.last ? descs.pop : {}
238
+ descs.flatten!
239
+ mdefault ||= get_kw('default', metadata)
240
+ descs.each do |desc|
241
+ names, default = Hash === desc ? desc.to_a.first : [desc, mdefault]
242
+ req = default ? false : required
243
+ names = [ names ] unless names.respond_to? :each
244
+ names.each do |name|
245
+ list << Keyword::new(name, metadata.merge('required'=>req,'default'=>default))
246
+ end
247
+ end
248
+ end
249
+ list
250
+ #--}}}
251
+ end
252
+ def required_keywords(*descs)
253
+ #--{{{
254
+ if descs.empty?
255
+ @required_keywords
256
+ else
257
+ define_keywords(@required_keywords, true, *descs)
258
+ end
259
+ #--}}}
260
+ end
261
+ alias required_keyword required_keywords
262
+ alias req_keywords required_keywords
263
+ alias req_keyword required_keywords
264
+ alias req_kws required_keywords
265
+ alias req_kw required_keywords
266
+ alias r_kws required_keywords
267
+ alias r_kw required_keywords
268
+ alias kws required_keywords
269
+ alias kw required_keywords
270
+ alias keywords required_keywords
271
+ alias keyword required_keywords
272
+ def optional_keywords(*descs)
273
+ #--{{{
274
+ if descs.empty?
275
+ @required_keywords
276
+ else
277
+ define_keywords(@optional_keywords, false, *descs)
278
+ end
279
+ #--}}}
280
+ end
281
+ alias optional_keyword optional_keywords
282
+ alias opt_keywords optional_keywords
283
+ alias opt_keyword optional_keywords
284
+ alias opt_kws optional_keywords
285
+ alias opt_kw optional_keywords
286
+ alias o_kws optional_keywords
287
+ alias o_kw optional_keywords
288
+ alias okws optional_keywords
289
+ alias okw optional_keywords
290
+ #
291
+ # TODO - thinks about *args signature??
292
+ #
293
+ def parse arg
294
+ #--{{{
295
+ enumerable, receiver =
296
+ if Hash === arg
297
+ a = arg.to_a
298
+ pair = a.shift
299
+ unless a.empty?
300
+ raise ArgumentError, "wrong number of arguments(#{ a.size + 1 } for 1"
301
+ end
302
+ pair
303
+ else
304
+ [arg, Receiver::new]
305
+ end
306
+
307
+ p_args = enumerable.to_enum.map
308
+
309
+ n = p_args.size
310
+
311
+ @required_arguments.each do |arg|
312
+ if p_args.empty?
313
+ raise ArgumentNotGiven, "<#{ arg.name }>"
314
+ end
315
+ p_arg = p_args.shift
316
+ arg.value = p_arg
317
+ receiver_set receiver, arg.name, arg.value
318
+ end
319
+
320
+ @optional_arguments.each do |arg|
321
+ p_arg = p_args.empty? ? arg.default : p_args.shift
322
+ arg.value = p_arg
323
+ receiver_set receiver, arg.name, arg.value
324
+ end
325
+
326
+ if receiver.respond_to? "arguments="
327
+ receiver.arguments = @required_arguments + @optional_arguments
328
+ end
329
+
330
+ p_kws = Hash === p_args.first ? p_args.shift : {}
331
+
332
+ @required_keywords.each do |kw|
333
+ p_kw, p_arg = extract_kw kw, p_kws
334
+ raise KeywordNotGiven, "<#{ kw.name }>" if p_kw.nil?
335
+ kw.value = p_arg
336
+ receiver_set receiver, kw.name, kw.value
337
+ end
338
+
339
+ @optional_keywords.each do |kw|
340
+ p_kw, p_arg = extract_kw kw, p_kws
341
+ p_arg = p_kw ? p_arg : kw.default
342
+ kw.value = p_arg
343
+ receiver_set receiver, kw.name, kw.value
344
+ end
345
+
346
+ if receiver.respond_to? "keywords="
347
+ receiver.keywords = @required_keywords + @optional_keywords
348
+ end
349
+
350
+ unless p_args.empty?
351
+ raise ArgumentError, "wrong number of arguments(#{ n } for #{ n - p_args.size })"
352
+ end
353
+
354
+ receiver
355
+ #--}}}
356
+ end
357
+ def extract_kw kw, kws
358
+ #--{{{
359
+ k = kw.name
360
+ return [k, kws[k]] if kws.has_key? k
361
+ k = "#{ k }"
362
+ return [k, kws[k]] if kws.has_key? k
363
+ k = k.intern
364
+ return [k, kws[k]] if kws.has_key? k
365
+ return [nil, nil]
366
+ #--}}}
367
+ end
368
+ def receiver_set receiver, name, value
369
+ #--{{{
370
+ begin
371
+ receiver.send "[]=", name, value
372
+ rescue NameError
373
+ begin
374
+ receiver.send "#{ name }=", value
375
+ rescue NameError
376
+ receiver.send "#{ name }", value
377
+ end
378
+ end
379
+ #--}}}
380
+ end
381
+ #--}}}
382
+ end # class Parser
383
+
384
+ class Receiver < ::Hash
385
+ #--{{{
386
+ include Util
387
+ attr_accessor 'arguments'
388
+ alias_method 'args', 'arguments'
389
+ attr_accessor 'keywords'
390
+ alias_method 'kws', 'keywords'
391
+ def method_missing(m, *a, &b)
392
+ #--{{{
393
+ return(get_kw(m)) if has_kw? m
394
+ super
395
+ #--}}}
396
+ end
397
+ #--}}}
398
+ end
399
+
400
+ module ModuleMethods
401
+ #--{{{
402
+ def parseargs(*____argv, &____block)
403
+ #--{{{
404
+ ::ParseArgs::parseargs(*____argv, &____block)
405
+ #--}}}
406
+ end
407
+ #--}}}
408
+ end # module ModuleMethods
409
+
410
+ module InstanceMethods
411
+ #--{{{
412
+ def parseargs(*____argv, &____block)
413
+ #--{{{
414
+ ::ParseArgs::parseargs(*____argv, &____block)
415
+ #--}}}
416
+ end
417
+ #--}}}
418
+ end # module InstanceMethods
419
+
420
+ class << self
421
+ #--{{{
422
+ def append_features klass
423
+ #--{{{
424
+ klass.extend ModuleMethods
425
+ klass.class_eval{ include InstanceMethods }
426
+ #--}}}
427
+ end
428
+ def parseargs(*____argv, &____block)
429
+ #--{{{
430
+ parser = ParseArgs::Parser::new(&____block)
431
+ receiver = parser.parse(*____argv)
432
+ receiver.freeze
433
+ receiver
434
+ #--}}}
435
+ end
436
+ #--}}}
437
+ end
438
+
439
+ #--}}}
440
+ end # module ParseArgs
441
+
442
+ class Object
443
+ #--{{{
444
+ def ParseArgs(*a, &b)
445
+ #--{{{
446
+ ::ParseArgs::parseargs(*a, &b)
447
+ #--}}}
448
+ end
449
+ #--}}}
450
+ end
451
+ $__parseargs__ = __FILE__
452
+ end
metadata ADDED
@@ -0,0 +1,40 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.8.11
3
+ specification_version: 1
4
+ name: parseargs
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.2.0
7
+ date: 2005-10-23 00:00:00.000000 -06:00
8
+ summary: parseargs
9
+ require_paths:
10
+ - lib
11
+ email: ara.t.howard@noaa.gov
12
+ homepage: http://codeforpeople.com/lib/ruby/parseargs/
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: parseargs
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ -
22
+ - ">"
23
+ - !ruby/object:Gem::Version
24
+ version: 0.0.0
25
+ version:
26
+ platform: ruby
27
+ signing_key:
28
+ cert_chain:
29
+ authors:
30
+ - Ara T. Howard
31
+ files:
32
+ - lib/parseargs.rb
33
+ - lib/parseargs-0.2.0.rb
34
+ test_files: []
35
+ rdoc_options: []
36
+ extra_rdoc_files: []
37
+ executables: []
38
+ extensions: []
39
+ requirements: []
40
+ dependencies: []