methopara 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +0 -0
- data/README +17 -0
- data/Rakefile +143 -0
- data/ext/extconf.rb +3 -0
- data/ext/methopara.c +501 -0
- data/lib/methopara.rb +1 -0
- 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
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
|
+
|