parseargs 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []