methopara 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. data/ChangeLog +0 -0
  2. data/README +17 -0
  3. data/Rakefile +143 -0
  4. data/ext/extconf.rb +3 -0
  5. data/ext/methopara.c +501 -0
  6. data/lib/methopara.rb +1 -0
  7. metadata +70 -0
data/ChangeLog ADDED
File without changes
data/README ADDED
@@ -0,0 +1,17 @@
1
+ methopara is stands for METHOd PARAmeters.
2
+
3
+ INSTALL:
4
+
5
+ sudo gem install methopara --source http://merbi.st
6
+
7
+ REQUIREMENT:
8
+
9
+ Ruby-1.9.1 only.
10
+
11
+ USAGE:
12
+
13
+ >> require "rubygems"
14
+ >> require "methopara"
15
+ >> def foo(a,b=nil,&c) end
16
+ >> method(:foo).parameters
17
+ => [[:req, :a], [:opt, :b], [:block, :c]]
data/Rakefile ADDED
@@ -0,0 +1,143 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'rake/clean'
4
+ require 'rake/testtask'
5
+ require 'rake/packagetask'
6
+ require 'rake/gempackagetask'
7
+ require 'rake/rdoctask'
8
+ require 'rake/contrib/rubyforgepublisher'
9
+ require 'rake/contrib/sshpublisher'
10
+ require 'fileutils'
11
+ include FileUtils
12
+
13
+ NAME = "methopara"
14
+ AUTHORS = ["Koichi Sasada", "Genki Takiuchi"]
15
+ EMAIL = "genki@s21g.com"
16
+ DESCRIPTION = "Method#parameters for ruby-1.9.1"
17
+ RUBYFORGE_PROJECT = "asakusarb"
18
+ HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
19
+ BIN_FILES = %w( )
20
+
21
+ VERS = "0.3.0"
22
+ REV = File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
23
+ CLEAN.include ['**/.*.sw?', '*.gem', '.config']
24
+ RDOC_OPTS = [
25
+ '--title', "#{NAME} documentation",
26
+ "--charset", "utf-8",
27
+ "--opname", "index.html",
28
+ "--line-numbers",
29
+ "--main", "README",
30
+ "--inline-source",
31
+ ]
32
+
33
+ task :default => [:test]
34
+ task :package => [:clean]
35
+
36
+ Rake::TestTask.new("test") do |t|
37
+ t.libs << "test"
38
+ t.pattern = "test/**/*_test.rb"
39
+ t.verbose = true
40
+ end
41
+
42
+ spec = Gem::Specification.new do |s|
43
+ s.name = NAME
44
+ s.version = VERS
45
+ s.platform = Gem::Platform::RUBY
46
+ s.has_rdoc = true
47
+ s.extra_rdoc_files = ["README", "ChangeLog"]
48
+ s.rdoc_options += RDOC_OPTS + ['--exclude', '^(examples|extras)/']
49
+ s.summary = DESCRIPTION
50
+ s.description = DESCRIPTION
51
+ s.authors = AUTHORS
52
+ s.email = EMAIL
53
+ s.homepage = HOMEPATH
54
+ s.executables = BIN_FILES
55
+ s.rubyforge_project = RUBYFORGE_PROJECT
56
+ s.bindir = "bin"
57
+ s.require_path = "lib"
58
+ #s.autorequire = ""
59
+ s.test_files = Dir["test/*_test.rb"]
60
+
61
+ #s.add_dependency('activesupport', '>=1.3.1')
62
+ s.required_ruby_version = '= 1.9.1'
63
+
64
+ s.files = %w(README ChangeLog Rakefile) +
65
+ Dir.glob("{bin,doc,test,lib,templates,generator,extras,website,script}/**/*") +
66
+ Dir.glob("*.{h,c,rb}") +
67
+ Dir.glob("examples/**/*.rb") +
68
+ Dir.glob("tools/*.rb") +
69
+ Dir.glob("ext/*.{h,c}")
70
+
71
+ s.extensions = ["ext/extconf.rb"]
72
+ end
73
+
74
+ Rake::GemPackageTask.new(spec) do |p|
75
+ p.need_tar = true
76
+ p.gem_spec = spec
77
+ end
78
+
79
+ task :install do
80
+ name = "#{NAME}-#{VERS}.gem"
81
+ sh %{rake package}
82
+ sh %{sudo gem install pkg/#{name}}
83
+ end
84
+
85
+ task :uninstall => [:clean] do
86
+ sh %{sudo gem uninstall #{NAME}}
87
+ end
88
+
89
+
90
+ Rake::RDocTask.new do |rdoc|
91
+ rdoc.rdoc_dir = 'html'
92
+ rdoc.options += RDOC_OPTS
93
+ rdoc.template = "resh"
94
+ #rdoc.template = "#{ENV['template']}.rb" if ENV['template']
95
+ if ENV['DOC_FILES']
96
+ rdoc.rdoc_files.include(ENV['DOC_FILES'].split(/,\s*/))
97
+ else
98
+ rdoc.rdoc_files.include('README', 'ChangeLog')
99
+ rdoc.rdoc_files.include('lib/**/*.rb')
100
+ rdoc.rdoc_files.include('**/*.c')
101
+ end
102
+ end
103
+
104
+ desc "Publish to RubyForge"
105
+ task :rubyforge => [:rdoc, :package] do
106
+ require 'rubyforge'
107
+ Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'takiuchi').upload
108
+ end
109
+
110
+ desc 'Package and upload the release to rubyforge.'
111
+ task :release => [:clean, :package] do |t|
112
+ v = ENV["VERSION"] or abort "Must supply VERSION=x.y.z"
113
+ abort "Versions don't match #{v} vs #{VERS}" unless v == VERS
114
+ pkg = "pkg/#{NAME}-#{VERS}"
115
+
116
+ require 'rubyforge'
117
+ rf = RubyForge.new.configure
118
+ puts "Logging in"
119
+ rf.login
120
+
121
+ c = rf.userconfig
122
+ # c["release_notes"] = description if description
123
+ # c["release_changes"] = changes if changes
124
+ c["preformatted"] = true
125
+
126
+ files = [
127
+ "#{pkg}.tgz",
128
+ "#{pkg}.gem"
129
+ ].compact
130
+
131
+ puts "Releasing #{NAME} v. #{VERS}"
132
+ rf.add_release RUBYFORGE_PROJECT, NAME, VERS, *files
133
+ end
134
+
135
+ desc 'Show information about the gem.'
136
+ task :debug_gem do
137
+ puts spec.to_ruby
138
+ end
139
+
140
+ desc 'Update gem spec'
141
+ task :gemspec do
142
+ open("#{NAME}.gemspec", 'w').write spec.to_ruby
143
+ end
data/ext/extconf.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile 'methopara'
data/ext/methopara.c ADDED
@@ -0,0 +1,501 @@
1
+ #include <ruby/ruby.h>
2
+
3
+ #define GetCoreDataFromValue(obj, type, ptr) do { \
4
+ ptr = (type*)DATA_PTR(obj); \
5
+ } while (0)
6
+
7
+ #define GetISeqPtr(obj, ptr) \
8
+ GetCoreDataFromValue(obj, rb_iseq_t, ptr)
9
+
10
+ typedef struct rb_proc_struct rb_proc_t;
11
+
12
+ typedef struct RNode {
13
+ unsigned long flags;
14
+ char *nd_file;
15
+ union {
16
+ struct RNode *node;
17
+ ID id;
18
+ VALUE value;
19
+ VALUE (*cfunc)(ANYARGS);
20
+ ID *tbl;
21
+ } u1;
22
+ union {
23
+ struct RNode *node;
24
+ ID id;
25
+ long argc;
26
+ VALUE value;
27
+ } u2;
28
+ union {
29
+ struct RNode *node;
30
+ ID id;
31
+ long state;
32
+ struct global_entry *entry;
33
+ long cnt;
34
+ VALUE value;
35
+ } u3;
36
+ } NODE;
37
+
38
+ typedef struct rb_iseq_struct {
39
+ /***************/
40
+ /* static data */
41
+ /***************/
42
+
43
+ VALUE type; /* instruction sequence type */
44
+ VALUE name; /* String: iseq name */
45
+ VALUE filename; /* file information where this sequence from */
46
+ VALUE *iseq; /* iseq (insn number and openrads) */
47
+ VALUE *iseq_encoded; /* encoded iseq */
48
+ unsigned long iseq_size;
49
+ VALUE mark_ary; /* Array: includes operands which should be GC marked */
50
+ VALUE coverage; /* coverage array */
51
+
52
+ /* insn info, must be freed */
53
+ struct iseq_insn_info_entry *insn_info_table;
54
+ unsigned long insn_info_size;
55
+
56
+ ID *local_table; /* must free */
57
+ int local_table_size;
58
+
59
+ /* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */
60
+ int local_size;
61
+
62
+ /**
63
+ * argument information
64
+ *
65
+ * def m(a1, a2, ..., aM, # mandatory
66
+ * b1=(...), b2=(...), ..., bN=(...), # optinal
67
+ * *c, # rest
68
+ * d1, d2, ..., dO, # post
69
+ * &e) # block
70
+ * =>
71
+ *
72
+ * argc = M
73
+ * arg_rest = M+N+1 // or -1 if no rest arg
74
+ * arg_opts = N
75
+ * arg_opts_tbl = [ (N entries) ]
76
+ * arg_post_len = O // 0 if no post arguments
77
+ * arg_post_start = M+N+2
78
+ * arg_block = M+N + 1 + O + 1 // -1 if no block arg
79
+ * arg_simple = 0 if not simple arguments.
80
+ * = 1 if no opt, rest, post, block.
81
+ * = 2 if ambiguos block parameter ({|a|}).
82
+ * arg_size = argument size.
83
+ */
84
+
85
+ int argc;
86
+ int arg_simple;
87
+ int arg_rest;
88
+ int arg_block;
89
+ int arg_opts;
90
+ int arg_post_len;
91
+ int arg_post_start;
92
+ int arg_size;
93
+ VALUE *arg_opt_table;
94
+
95
+ int stack_max; /* for stack overflow check */
96
+
97
+ /* catch table */
98
+ struct iseq_catch_table_entry *catch_table;
99
+ int catch_table_size;
100
+
101
+ /* for child iseq */
102
+ struct rb_iseq_struct *parent_iseq;
103
+ struct rb_iseq_struct *local_iseq;
104
+
105
+ /****************/
106
+ /* dynamic data */
107
+ /****************/
108
+
109
+ VALUE self;
110
+ VALUE orig; /* non-NULL if its data have origin */
111
+
112
+ /* block inlining */
113
+ /*
114
+ * NODE *node;
115
+ * void *special_block_builder;
116
+ * void *cached_special_block_builder;
117
+ * VALUE cached_special_block;
118
+ */
119
+
120
+ /* klass/module nest information stack (cref) */
121
+ NODE *cref_stack;
122
+ VALUE klass;
123
+
124
+ /* misc */
125
+ ID defined_method_id; /* for define_method */
126
+
127
+ /* used at compile time */
128
+ struct iseq_compile_data *compile_data;
129
+ } rb_iseq_t;
130
+
131
+ struct METHOD {
132
+ VALUE oclass; /* class that holds the method */
133
+ VALUE rclass; /* class of the receiver */
134
+ VALUE recv;
135
+ ID id, oid;
136
+ NODE *body;
137
+ };
138
+
139
+ enum node_type {
140
+ NODE_METHOD,
141
+ #define NODE_METHOD NODE_METHOD
142
+ NODE_FBODY,
143
+ #define NODE_FBODY NODE_FBODY
144
+ NODE_CFUNC,
145
+ #define NODE_CFUNC NODE_CFUNC
146
+ NODE_SCOPE,
147
+ #define NODE_SCOPE NODE_SCOPE
148
+ NODE_BLOCK,
149
+ #define NODE_BLOCK NODE_BLOCK
150
+ NODE_IF,
151
+ #define NODE_IF NODE_IF
152
+ NODE_CASE,
153
+ #define NODE_CASE NODE_CASE
154
+ NODE_WHEN,
155
+ #define NODE_WHEN NODE_WHEN
156
+ NODE_OPT_N,
157
+ #define NODE_OPT_N NODE_OPT_N
158
+ NODE_WHILE,
159
+ #define NODE_WHILE NODE_WHILE
160
+ NODE_UNTIL,
161
+ #define NODE_UNTIL NODE_UNTIL
162
+ NODE_ITER,
163
+ #define NODE_ITER NODE_ITER
164
+ NODE_FOR,
165
+ #define NODE_FOR NODE_FOR
166
+ NODE_BREAK,
167
+ #define NODE_BREAK NODE_BREAK
168
+ NODE_NEXT,
169
+ #define NODE_NEXT NODE_NEXT
170
+ NODE_REDO,
171
+ #define NODE_REDO NODE_REDO
172
+ NODE_RETRY,
173
+ #define NODE_RETRY NODE_RETRY
174
+ NODE_BEGIN,
175
+ #define NODE_BEGIN NODE_BEGIN
176
+ NODE_RESCUE,
177
+ #define NODE_RESCUE NODE_RESCUE
178
+ NODE_RESBODY,
179
+ #define NODE_RESBODY NODE_RESBODY
180
+ NODE_ENSURE,
181
+ #define NODE_ENSURE NODE_ENSURE
182
+ NODE_AND,
183
+ #define NODE_AND NODE_AND
184
+ NODE_OR,
185
+ #define NODE_OR NODE_OR
186
+ NODE_MASGN,
187
+ #define NODE_MASGN NODE_MASGN
188
+ NODE_LASGN,
189
+ #define NODE_LASGN NODE_LASGN
190
+ NODE_DASGN,
191
+ #define NODE_DASGN NODE_DASGN
192
+ NODE_DASGN_CURR,
193
+ #define NODE_DASGN_CURR NODE_DASGN_CURR
194
+ NODE_GASGN,
195
+ #define NODE_GASGN NODE_GASGN
196
+ NODE_IASGN,
197
+ #define NODE_IASGN NODE_IASGN
198
+ NODE_IASGN2,
199
+ #define NODE_IASGN2 NODE_IASGN2
200
+ NODE_CDECL,
201
+ #define NODE_CDECL NODE_CDECL
202
+ NODE_CVASGN,
203
+ #define NODE_CVASGN NODE_CVASGN
204
+ NODE_CVDECL,
205
+ #define NODE_CVDECL NODE_CVDECL
206
+ NODE_OP_ASGN1,
207
+ #define NODE_OP_ASGN1 NODE_OP_ASGN1
208
+ NODE_OP_ASGN2,
209
+ #define NODE_OP_ASGN2 NODE_OP_ASGN2
210
+ NODE_OP_ASGN_AND,
211
+ #define NODE_OP_ASGN_AND NODE_OP_ASGN_AND
212
+ NODE_OP_ASGN_OR,
213
+ #define NODE_OP_ASGN_OR NODE_OP_ASGN_OR
214
+ NODE_CALL,
215
+ #define NODE_CALL NODE_CALL
216
+ NODE_FCALL,
217
+ #define NODE_FCALL NODE_FCALL
218
+ NODE_VCALL,
219
+ #define NODE_VCALL NODE_VCALL
220
+ NODE_SUPER,
221
+ #define NODE_SUPER NODE_SUPER
222
+ NODE_ZSUPER,
223
+ #define NODE_ZSUPER NODE_ZSUPER
224
+ NODE_ARRAY,
225
+ #define NODE_ARRAY NODE_ARRAY
226
+ NODE_ZARRAY,
227
+ #define NODE_ZARRAY NODE_ZARRAY
228
+ NODE_VALUES,
229
+ #define NODE_VALUES NODE_VALUES
230
+ NODE_HASH,
231
+ #define NODE_HASH NODE_HASH
232
+ NODE_RETURN,
233
+ #define NODE_RETURN NODE_RETURN
234
+ NODE_YIELD,
235
+ #define NODE_YIELD NODE_YIELD
236
+ NODE_LVAR,
237
+ #define NODE_LVAR NODE_LVAR
238
+ NODE_DVAR,
239
+ #define NODE_DVAR NODE_DVAR
240
+ NODE_GVAR,
241
+ #define NODE_GVAR NODE_GVAR
242
+ NODE_IVAR,
243
+ #define NODE_IVAR NODE_IVAR
244
+ NODE_CONST,
245
+ #define NODE_CONST NODE_CONST
246
+ NODE_CVAR,
247
+ #define NODE_CVAR NODE_CVAR
248
+ NODE_NTH_REF,
249
+ #define NODE_NTH_REF NODE_NTH_REF
250
+ NODE_BACK_REF,
251
+ #define NODE_BACK_REF NODE_BACK_REF
252
+ NODE_MATCH,
253
+ #define NODE_MATCH NODE_MATCH
254
+ NODE_MATCH2,
255
+ #define NODE_MATCH2 NODE_MATCH2
256
+ NODE_MATCH3,
257
+ #define NODE_MATCH3 NODE_MATCH3
258
+ NODE_LIT,
259
+ #define NODE_LIT NODE_LIT
260
+ NODE_STR,
261
+ #define NODE_STR NODE_STR
262
+ NODE_DSTR,
263
+ #define NODE_DSTR NODE_DSTR
264
+ NODE_XSTR,
265
+ #define NODE_XSTR NODE_XSTR
266
+ NODE_DXSTR,
267
+ #define NODE_DXSTR NODE_DXSTR
268
+ NODE_EVSTR,
269
+ #define NODE_EVSTR NODE_EVSTR
270
+ NODE_DREGX,
271
+ #define NODE_DREGX NODE_DREGX
272
+ NODE_DREGX_ONCE,
273
+ #define NODE_DREGX_ONCE NODE_DREGX_ONCE
274
+ NODE_ARGS,
275
+ #define NODE_ARGS NODE_ARGS
276
+ NODE_ARGS_AUX,
277
+ #define NODE_ARGS_AUX NODE_ARGS_AUX
278
+ NODE_OPT_ARG,
279
+ #define NODE_OPT_ARG NODE_OPT_ARG
280
+ NODE_POSTARG,
281
+ #define NODE_POSTARG NODE_POSTARG
282
+ NODE_ARGSCAT,
283
+ #define NODE_ARGSCAT NODE_ARGSCAT
284
+ NODE_ARGSPUSH,
285
+ #define NODE_ARGSPUSH NODE_ARGSPUSH
286
+ NODE_SPLAT,
287
+ #define NODE_SPLAT NODE_SPLAT
288
+ NODE_TO_ARY,
289
+ #define NODE_TO_ARY NODE_TO_ARY
290
+ NODE_BLOCK_ARG,
291
+ #define NODE_BLOCK_ARG NODE_BLOCK_ARG
292
+ NODE_BLOCK_PASS,
293
+ #define NODE_BLOCK_PASS NODE_BLOCK_PASS
294
+ NODE_DEFN,
295
+ #define NODE_DEFN NODE_DEFN
296
+ NODE_DEFS,
297
+ #define NODE_DEFS NODE_DEFS
298
+ NODE_ALIAS,
299
+ #define NODE_ALIAS NODE_ALIAS
300
+ NODE_VALIAS,
301
+ #define NODE_VALIAS NODE_VALIAS
302
+ NODE_UNDEF,
303
+ #define NODE_UNDEF NODE_UNDEF
304
+ NODE_CLASS,
305
+ #define NODE_CLASS NODE_CLASS
306
+ NODE_MODULE,
307
+ #define NODE_MODULE NODE_MODULE
308
+ NODE_SCLASS,
309
+ #define NODE_SCLASS NODE_SCLASS
310
+ NODE_COLON2,
311
+ #define NODE_COLON2 NODE_COLON2
312
+ NODE_COLON3,
313
+ #define NODE_COLON3 NODE_COLON3
314
+ NODE_DOT2,
315
+ #define NODE_DOT2 NODE_DOT2
316
+ NODE_DOT3,
317
+ #define NODE_DOT3 NODE_DOT3
318
+ NODE_FLIP2,
319
+ #define NODE_FLIP2 NODE_FLIP2
320
+ NODE_FLIP3,
321
+ #define NODE_FLIP3 NODE_FLIP3
322
+ NODE_ATTRSET,
323
+ #define NODE_ATTRSET NODE_ATTRSET
324
+ NODE_SELF,
325
+ #define NODE_SELF NODE_SELF
326
+ NODE_NIL,
327
+ #define NODE_NIL NODE_NIL
328
+ NODE_TRUE,
329
+ #define NODE_TRUE NODE_TRUE
330
+ NODE_FALSE,
331
+ #define NODE_FALSE NODE_FALSE
332
+ NODE_ERRINFO,
333
+ #define NODE_ERRINFO NODE_ERRINFO
334
+ NODE_DEFINED,
335
+ #define NODE_DEFINED NODE_DEFINED
336
+ NODE_POSTEXE,
337
+ #define NODE_POSTEXE NODE_POSTEXE
338
+ NODE_ALLOCA,
339
+ #define NODE_ALLOCA NODE_ALLOCA
340
+ NODE_BMETHOD,
341
+ #define NODE_BMETHOD NODE_BMETHOD
342
+ NODE_MEMO,
343
+ #define NODE_MEMO NODE_MEMO
344
+ NODE_IFUNC,
345
+ #define NODE_IFUNC NODE_IFUNC
346
+ NODE_DSYM,
347
+ #define NODE_DSYM NODE_DSYM
348
+ NODE_ATTRASGN,
349
+ #define NODE_ATTRASGN NODE_ATTRASGN
350
+ NODE_PRELUDE,
351
+ #define NODE_PRELUDE NODE_PRELUDE
352
+ NODE_LAMBDA,
353
+ #define NODE_LAMBDA NODE_LAMBDA
354
+ NODE_OPTBLOCK,
355
+ #define NODE_OPTBLOCK NODE_OPTBLOCK
356
+ NODE_LAST
357
+ #define NODE_LAST NODE_LAST
358
+ };
359
+
360
+ #define RUBY_VM_METHOD_NODE NODE_METHOD
361
+ #define nd_body u2.node
362
+
363
+ #define NODE_TYPESHIFT 8
364
+ #define NODE_TYPEMASK (((VALUE)0x7f)<<NODE_TYPESHIFT)
365
+ #define RNODE(obj) (R_CAST(RNode)(obj))
366
+ #define nd_type(n) ((int) (((RNODE(n))->flags & NODE_TYPEMASK)>>NODE_TYPESHIFT))
367
+ #define RUBY_VM_IFUNC_P(ptr) (BUILTIN_TYPE(ptr) == T_NODE)
368
+ #define RUBY_VM_NORMAL_ISEQ_P(ptr) \
369
+ (ptr && !RUBY_VM_IFUNC_P(ptr))
370
+
371
+ static VALUE
372
+ rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc)
373
+ {
374
+ int i, r, s;
375
+ VALUE a, args = rb_ary_new2(iseq->arg_size);
376
+ ID req, opt, rest, block;
377
+ #define PARAM_TYPE(type) rb_ary_push(a = rb_ary_new2(2), ID2SYM(type))
378
+ #define PARAM_ID(i) iseq->local_table[i]
379
+ #define PARAM(i, type) ( \
380
+ PARAM_TYPE(type), \
381
+ rb_id2name(PARAM_ID(i)) ? \
382
+ rb_ary_push(a, ID2SYM(PARAM_ID(i))) : \
383
+ a)
384
+
385
+ CONST_ID(req, "req");
386
+ CONST_ID(opt, "opt");
387
+ if (is_proc) {
388
+ for (i = 0; i < iseq->argc; i++) {
389
+ PARAM_TYPE(opt);
390
+ rb_ary_push(a, rb_id2name(PARAM_ID(i)) ?
391
+ ID2SYM(PARAM_ID(i)) : Qnil);
392
+ rb_ary_push(a, Qnil);
393
+ rb_ary_push(args, a);
394
+ }
395
+ }
396
+ else {
397
+ for (i = 0; i < iseq->argc; i++) {
398
+ rb_ary_push(args, PARAM(i, req));
399
+ }
400
+ }
401
+ r = iseq->arg_rest != -1 ? iseq->arg_rest :
402
+ iseq->arg_post_len > 0 ? iseq->arg_post_start :
403
+ iseq->arg_block != -1 ? iseq->arg_block :
404
+ iseq->arg_size;
405
+ for (s = i; i < r; i++) {
406
+ PARAM_TYPE(opt);
407
+ if (rb_id2name(PARAM_ID(i))) {
408
+ rb_ary_push(a, ID2SYM(PARAM_ID(i)));
409
+ }
410
+ rb_ary_push(args, a);
411
+ }
412
+ if (iseq->arg_rest != -1) {
413
+ CONST_ID(rest, "rest");
414
+ rb_ary_push(args, PARAM(iseq->arg_rest, rest));
415
+ }
416
+ r = iseq->arg_post_start + iseq->arg_post_len;
417
+ if (is_proc) {
418
+ for (i = iseq->arg_post_start; i < r; i++) {
419
+ PARAM_TYPE(opt);
420
+ rb_ary_push(a, rb_id2name(PARAM_ID(i)) ?
421
+ ID2SYM(PARAM_ID(i)) : Qnil);
422
+ rb_ary_push(a, Qnil);
423
+ rb_ary_push(args, a);
424
+ }
425
+ }
426
+ else {
427
+ for (i = iseq->arg_post_start; i < r; i++) {
428
+ rb_ary_push(args, PARAM(i, req));
429
+ }
430
+ }
431
+ if (iseq->arg_block != -1) {
432
+ CONST_ID(block, "block");
433
+ rb_ary_push(args, PARAM(iseq->arg_block, block));
434
+ }
435
+ return args;
436
+ }
437
+
438
+ static rb_iseq_t *
439
+ get_method_iseq(VALUE method)
440
+ {
441
+ struct METHOD *data;
442
+ NODE *body;
443
+ rb_iseq_t *iseq;
444
+
445
+ Data_Get_Struct(method, struct METHOD, data);
446
+ body = data->body;
447
+ switch (nd_type(body)) {
448
+ case NODE_BMETHOD:
449
+ rb_notimplement();
450
+ case RUBY_VM_METHOD_NODE:
451
+ GetISeqPtr((VALUE)body->nd_body, iseq);
452
+ if (RUBY_VM_NORMAL_ISEQ_P(iseq)) break;
453
+ default:
454
+ return 0;
455
+ }
456
+ return iseq;
457
+ }
458
+
459
+ static VALUE
460
+ unnamed_parameters(int arity)
461
+ {
462
+ VALUE a, param = rb_ary_new2((arity < 0) ? -arity : arity);
463
+ int n = (arity < 0) ? ~arity : arity;
464
+ ID req, rest;
465
+ CONST_ID(req, "req");
466
+ a = rb_ary_new3(1, ID2SYM(req));
467
+ OBJ_FREEZE(a);
468
+ for (; n; --n) {
469
+ rb_ary_push(param, a);
470
+ }
471
+ if (arity < 0) {
472
+ CONST_ID(rest, "rest");
473
+ rb_ary_store(param, ~arity, rb_ary_new3(1, ID2SYM(rest)));
474
+ }
475
+ return param;
476
+ }
477
+
478
+ /*
479
+ * call-seq:
480
+ * meth.parameters => array
481
+ *
482
+ * returns the parameter information of this method
483
+ */
484
+
485
+ static VALUE
486
+ rb_method_parameters(VALUE method)
487
+ {
488
+ rb_iseq_t *iseq = get_method_iseq(method);
489
+ if (!iseq) {
490
+ return unnamed_parameters(
491
+ FIX2INT(rb_funcall(method, rb_intern("arity"), 0)));
492
+ }
493
+ return rb_iseq_parameters(iseq, 0);
494
+ }
495
+
496
+ void
497
+ Init_methopara(void)
498
+ {
499
+ rb_define_method(rb_cMethod, "parameters", rb_method_parameters, 0);
500
+ rb_define_method(rb_cUnboundMethod, "parameters", rb_method_parameters, 0);
501
+ }
data/lib/methopara.rb ADDED
@@ -0,0 +1 @@
1
+ require File.join(File.dirname(__FILE__), %w(.. ext methopara))
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: methopara
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Koichi Sasada
8
+ - Genki Takiuchi
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-02-14 00:00:00 +09:00
14
+ default_executable:
15
+ dependencies: []
16
+
17
+ description: Method#parameters for ruby-1.9.1
18
+ email: genki@s21g.com
19
+ executables: []
20
+
21
+ extensions:
22
+ - ext/extconf.rb
23
+ extra_rdoc_files:
24
+ - README
25
+ - ChangeLog
26
+ files:
27
+ - README
28
+ - ChangeLog
29
+ - Rakefile
30
+ - lib/methopara.rb
31
+ - ext/methopara.c
32
+ has_rdoc: true
33
+ homepage: http://asakusarb.rubyforge.org
34
+ post_install_message:
35
+ rdoc_options:
36
+ - --title
37
+ - methopara documentation
38
+ - --charset
39
+ - utf-8
40
+ - --opname
41
+ - index.html
42
+ - --line-numbers
43
+ - --main
44
+ - README
45
+ - --inline-source
46
+ - --exclude
47
+ - ^(examples|extras)/
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "="
53
+ - !ruby/object:Gem::Version
54
+ version: 1.9.1
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project: asakusarb
65
+ rubygems_version: 1.3.1
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: Method#parameters for ruby-1.9.1
69
+ test_files: []
70
+