From: nobu@... Date: 2004-12-09T14:00:23+09:00 Subject: [ruby-dev:25147] Re: Set/test_eq failed on Tru64UNIX なかだです。 At Thu, 9 Dec 2004 13:36:14 +0900, Yukihiro Matsumoto wrote in [ruby-dev:25146]: > |coreと標準ライブラリで数えてみると、inspectを定義しているのはC > |で15、rubyで59ありました。これだけならともかく、外部のものまで > |考えると、pも使えなくなるのはちょっと痛いような気がします。 > |inspectのarityを見るというのはどうでしょうか。 > > arityって簡単にチェックできましたっけ。funcall_rescueを使っ > てとりあえず呼んでみるとか。で、普段から-dを使ってる人が悲鳴 > を上げると。 method_arity()から分離すればそう大変ではないと思いますが。 呼び出し側はこんな感じで。 arity = rb_method_arity(rb_method_node(CLASS_OF(obj), id_inspect)); result = rb_funcall2(obj, id_inspect, arity != 0, &context); Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.745 diff -U2 -p -d -r1.745 eval.c --- eval.c 9 Dec 2004 02:19:50 -0000 1.745 +++ eval.c 9 Dec 2004 04:59:54 -0000 @@ -8338,6 +8338,6 @@ proc_call(proc, args) */ -static VALUE -proc_arity(proc) +VALUE +rb_proc_arity(proc) VALUE proc; { @@ -8353,16 +8353,16 @@ proc_arity(proc) return method_arity(data->body->nd_tval); } - return INT2FIX(0); + return 0; } - if (var == (NODE*)1) return INT2FIX(0); - if (var == (NODE*)2) return INT2FIX(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 INT2FIX(0); - if (var == (NODE*)2) return INT2FIX(0); + if (var == (NODE*)1) return 0; + if (var == (NODE*)2) return 0; } switch (nd_type(var)) { default: - return INT2FIX(1); + return 1; case NODE_MASGN: list = var->nd_head; @@ -8372,9 +8372,17 @@ proc_arity(proc) list = list->nd_next; } - if (var->nd_args) return INT2FIX(-n-1); - return INT2FIX(n); + if (var->nd_args) return -n-1; + return n; } } +static VALUE +proc_arity(proc) + VALUE proc; +{ + int arity = rb_proc_arity(proc); + return INT2FIX(arity); +} + /* * call-seq: @@ -9029,4 +9037,32 @@ umethod_bind(method, recv) } +int +rb_method_arity(body) + NODE *body; +{ + 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); + default: + 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; + } +} + /* * call-seq: @@ -9067,32 +9103,9 @@ method_arity(method) { struct METHOD *data; - NODE *body; int n; Data_Get_Struct(method, struct METHOD, data); - - body = data->body; - switch (nd_type(body)) { - case NODE_CFUNC: - if (body->nd_argc < 0) return INT2FIX(-1); - return INT2FIX(body->nd_argc); - case NODE_ZSUPER: - return INT2FIX(-1); - case NODE_ATTRSET: - return INT2FIX(1); - case NODE_IVAR: - return INT2FIX(0); - case NODE_BMETHOD: - return proc_arity(body->nd_cval); - default: - body = body->nd_next; /* skip NODE_SCOPE */ - 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); - } + n = rb_method_arity(data->body); + return INT2FIX(n); } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦