/* * call-seq: * prc.arity -> fixnum * * Returns the number of arguments that would not be ignored. If the block * is declared to take no arguments, returns 0. If the block is known * to take exactly n arguments, returns n. If the block has optional * arguments, return -n-1, where n is the number of mandatory * arguments. A <code>proc</code> with no argument declarations * is the same a block declaring <code>||</code> as its arguments. * * Proc.new {}.arity #=> 0 * Proc.new {||}.arity #=> 0 * Proc.new {|a|}.arity #=> 1 * Proc.new {|a,b|}.arity #=> 2 * Proc.new {|a,b,c|}.arity #=> 3 * Proc.new {|*a|}.arity #=> -1 * Proc.new {|a,*b|}.arity #=> -2 */ static VALUE proc_arity(proc) VALUE proc; { struct BLOCK *data; NODE *list; int n; Data_Get_Struct(proc, struct BLOCK, data); if (data->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(-1); } if (data->var == (NODE*)1) return INT2FIX(0); if (data->var == (NODE*)2) return INT2FIX(0); switch (nd_type(data->var)) { default: return INT2FIX(1); case NODE_MASGN: list = data->var->nd_head; n = 0; while (list) { n++; list = list->nd_next; } if (data->var->nd_args) return INT2FIX(-n-1); return INT2FIX(n); } }