mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (rb_proc_arity, rb_node_arity, rb_mod_method_arity,
rb_obj_method_arity): new functions to obtain method arity. [ruby-dev:25143] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@7583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
326ebac3db
commit
7910c3fd56
3 changed files with 106 additions and 62 deletions
164
eval.c
164
eval.c
|
@ -4581,7 +4581,7 @@ break_jump(retval)
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE bmcall _((VALUE, VALUE));
|
static VALUE bmcall _((VALUE, VALUE));
|
||||||
static VALUE method_arity _((VALUE));
|
static int method_arity _((VALUE));
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
kk()
|
kk()
|
||||||
|
@ -8275,6 +8275,45 @@ proc_call(proc, args)
|
||||||
return proc_invoke(proc, args, Qundef, 0);
|
return proc_invoke(proc, args, Qundef, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_proc_arity(proc)
|
||||||
|
VALUE proc;
|
||||||
|
{
|
||||||
|
struct BLOCK *data;
|
||||||
|
NODE *var, *list;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
Data_Get_Struct(proc, struct BLOCK, data);
|
||||||
|
var = data->var;
|
||||||
|
if (var == 0) {
|
||||||
|
if (data->body && nd_type(data->body) == NODE_IFUNC &&
|
||||||
|
data->body->nd_cfnc == bmcall) {
|
||||||
|
return method_arity(data->body->nd_tval);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (var == (NODE*)1) return 0;
|
||||||
|
if (var == (NODE*)2) return 0;
|
||||||
|
if (nd_type(var) == NODE_BLOCK_ARG) {
|
||||||
|
var = var->nd_args;
|
||||||
|
if (var == (NODE*)1) return 0;
|
||||||
|
if (var == (NODE*)2) return 0;
|
||||||
|
}
|
||||||
|
switch (nd_type(var)) {
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
case NODE_MASGN:
|
||||||
|
list = var->nd_head;
|
||||||
|
n = 0;
|
||||||
|
while (list) {
|
||||||
|
n++;
|
||||||
|
list = list->nd_next;
|
||||||
|
}
|
||||||
|
if (var->nd_args) return -n-1;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* prc.arity -> fixnum
|
* prc.arity -> fixnum
|
||||||
|
@ -8299,39 +8338,8 @@ static VALUE
|
||||||
proc_arity(proc)
|
proc_arity(proc)
|
||||||
VALUE proc;
|
VALUE proc;
|
||||||
{
|
{
|
||||||
struct BLOCK *data;
|
int arity = rb_proc_arity(proc);
|
||||||
NODE *var, *list;
|
return INT2FIX(arity);
|
||||||
int n;
|
|
||||||
|
|
||||||
Data_Get_Struct(proc, struct BLOCK, data);
|
|
||||||
var = data->var;
|
|
||||||
if (var == 0) {
|
|
||||||
if (data->body && nd_type(data->body) == NODE_IFUNC &&
|
|
||||||
data->body->nd_cfnc == bmcall) {
|
|
||||||
return method_arity(data->body->nd_tval);
|
|
||||||
}
|
|
||||||
return INT2FIX(0);
|
|
||||||
}
|
|
||||||
if (var == (NODE*)1) return INT2FIX(0);
|
|
||||||
if (var == (NODE*)2) return INT2FIX(0);
|
|
||||||
if (nd_type(var) == NODE_BLOCK_ARG) {
|
|
||||||
var = var->nd_args;
|
|
||||||
if (var == (NODE*)1) return INT2FIX(0);
|
|
||||||
if (var == (NODE*)2) return INT2FIX(0);
|
|
||||||
}
|
|
||||||
switch (nd_type(var)) {
|
|
||||||
default:
|
|
||||||
return INT2FIX(1);
|
|
||||||
case NODE_MASGN:
|
|
||||||
list = var->nd_head;
|
|
||||||
n = 0;
|
|
||||||
while (list) {
|
|
||||||
n++;
|
|
||||||
list = list->nd_next;
|
|
||||||
}
|
|
||||||
if (var->nd_args) return INT2FIX(-n-1);
|
|
||||||
return INT2FIX(n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -8612,7 +8620,7 @@ mnew(klass, obj, id, mklass)
|
||||||
rklass = RCLASS(rklass)->super;
|
rklass = RCLASS(rklass)->super;
|
||||||
}
|
}
|
||||||
if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;
|
if (TYPE(klass) == T_ICLASS) klass = RBASIC(klass)->klass;
|
||||||
method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);
|
method = Data_Make_Struct(mklass, struct METHOD, bm_mark, -1, data);
|
||||||
data->klass = klass;
|
data->klass = klass;
|
||||||
data->recv = obj;
|
data->recv = obj;
|
||||||
data->id = id;
|
data->id = id;
|
||||||
|
@ -8986,6 +8994,38 @@ umethod_bind(method, recv)
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
rb_node_arity(body)
|
||||||
|
NODE *body;
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
switch (nd_type(body)) {
|
||||||
|
case NODE_CFUNC:
|
||||||
|
if (body->nd_argc < 0) return -1;
|
||||||
|
return body->nd_argc;
|
||||||
|
case NODE_ZSUPER:
|
||||||
|
return -1;
|
||||||
|
case NODE_ATTRSET:
|
||||||
|
return 1;
|
||||||
|
case NODE_IVAR:
|
||||||
|
return 0;
|
||||||
|
case NODE_BMETHOD:
|
||||||
|
return rb_proc_arity(body->nd_cval);
|
||||||
|
case NODE_SCOPE:
|
||||||
|
body = body->nd_next; /* skip NODE_SCOPE */
|
||||||
|
if (nd_type(body) == NODE_BLOCK)
|
||||||
|
body = body->nd_head;
|
||||||
|
if (!body) return 0;
|
||||||
|
n = body->nd_cnt;
|
||||||
|
if (body->nd_opt || body->nd_rest != -1)
|
||||||
|
n = -n-1;
|
||||||
|
return n;
|
||||||
|
default:
|
||||||
|
rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* meth.arity => fixnum
|
* meth.arity => fixnum
|
||||||
|
@ -9020,38 +9060,38 @@ umethod_bind(method, recv)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
method_arity_m(method)
|
||||||
|
VALUE method;
|
||||||
|
{
|
||||||
|
int n = method_arity(method);
|
||||||
|
return INT2FIX(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
method_arity(method)
|
method_arity(method)
|
||||||
VALUE method;
|
VALUE method;
|
||||||
{
|
{
|
||||||
struct METHOD *data;
|
struct METHOD *data;
|
||||||
NODE *body;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
Data_Get_Struct(method, struct METHOD, data);
|
Data_Get_Struct(method, struct METHOD, data);
|
||||||
|
return rb_node_arity(data->body);
|
||||||
|
}
|
||||||
|
|
||||||
body = data->body;
|
int
|
||||||
switch (nd_type(body)) {
|
rb_mod_method_arity(mod, id)
|
||||||
case NODE_CFUNC:
|
VALUE mod;
|
||||||
if (body->nd_argc < 0) return INT2FIX(-1);
|
ID id;
|
||||||
return INT2FIX(body->nd_argc);
|
{
|
||||||
case NODE_ZSUPER:
|
NODE *node = rb_method_node(mod, id);
|
||||||
return INT2FIX(-1);
|
return rb_node_arity(node);
|
||||||
case NODE_ATTRSET:
|
}
|
||||||
return INT2FIX(1);
|
|
||||||
case NODE_IVAR:
|
int
|
||||||
return INT2FIX(0);
|
rb_obj_method_arity(obj, id)
|
||||||
case NODE_BMETHOD:
|
VALUE obj;
|
||||||
return proc_arity(body->nd_cval);
|
ID id;
|
||||||
default:
|
{
|
||||||
body = body->nd_next; /* skip NODE_SCOPE */
|
return rb_mod_method_arity(CLASS_OF(obj), id);
|
||||||
if (nd_type(body) == NODE_BLOCK)
|
|
||||||
body = body->nd_head;
|
|
||||||
if (!body) return INT2FIX(0);
|
|
||||||
n = body->nd_cnt;
|
|
||||||
if (body->nd_opt || body->nd_rest != -1)
|
|
||||||
n = -n-1;
|
|
||||||
return INT2FIX(n);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -9360,7 +9400,7 @@ Init_Proc()
|
||||||
rb_define_method(rb_cMethod, "clone", method_clone, 0);
|
rb_define_method(rb_cMethod, "clone", method_clone, 0);
|
||||||
rb_define_method(rb_cMethod, "call", method_call, -1);
|
rb_define_method(rb_cMethod, "call", method_call, -1);
|
||||||
rb_define_method(rb_cMethod, "[]", method_call, -1);
|
rb_define_method(rb_cMethod, "[]", method_call, -1);
|
||||||
rb_define_method(rb_cMethod, "arity", method_arity, 0);
|
rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
|
||||||
rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
|
rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
|
||||||
rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
|
rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
|
||||||
rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
|
rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
|
||||||
|
@ -9374,7 +9414,7 @@ Init_Proc()
|
||||||
rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
|
rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
|
||||||
rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
|
rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
|
rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "arity", method_arity, 0);
|
rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
|
rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
|
rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
|
||||||
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
|
rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
|
||||||
|
|
3
intern.h
3
intern.h
|
@ -190,6 +190,9 @@ VALUE rb_class_new_instance _((int, VALUE*, VALUE));
|
||||||
VALUE rb_block_proc _((void));
|
VALUE rb_block_proc _((void));
|
||||||
VALUE rb_f_lambda _((void));
|
VALUE rb_f_lambda _((void));
|
||||||
VALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
|
VALUE rb_proc_new _((VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE));
|
||||||
|
int rb_proc_arity _((VALUE));
|
||||||
|
int rb_mod_method_arity _((VALUE, ID));
|
||||||
|
int rb_obj_method_arity _((VALUE, ID));
|
||||||
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
|
VALUE rb_protect _((VALUE (*)(VALUE), VALUE, int*));
|
||||||
void rb_set_end_proc _((void (*)(VALUE), VALUE));
|
void rb_set_end_proc _((void (*)(VALUE), VALUE));
|
||||||
void rb_mark_end_proc _((void));
|
void rb_mark_end_proc _((void));
|
||||||
|
|
1
node.h
1
node.h
|
@ -357,6 +357,7 @@ void rb_add_method _((VALUE, ID, NODE *, int));
|
||||||
NODE *rb_node_newnode _((enum node_type,VALUE,VALUE,VALUE));
|
NODE *rb_node_newnode _((enum node_type,VALUE,VALUE,VALUE));
|
||||||
|
|
||||||
NODE* rb_method_node _((VALUE klass, ID id));
|
NODE* rb_method_node _((VALUE klass, ID id));
|
||||||
|
int rb_node_arity _((NODE* node));
|
||||||
|
|
||||||
struct global_entry *rb_global_entry _((ID));
|
struct global_entry *rb_global_entry _((ID));
|
||||||
VALUE rb_gvar_get _((struct global_entry *));
|
VALUE rb_gvar_get _((struct global_entry *));
|
||||||
|
|
Loading…
Reference in a new issue