summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--hash.c6
-rw-r--r--include/ruby/intern.h1
-rw-r--r--proc.c8
4 files changed, 16 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 0d294d2d03..a836c16396 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Oct 24 14:28:40 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * hash.c (rb_hash_set_default_proc): checks arity of defalt_proc
+ of a Hash. [ruby-core:26087]
+
Sat Oct 24 13:38:45 2009 Yukihiro Matsumoto <matz@ruby-lang.org>
* object.c (rb_obj_cmp): defines Object#<=>. [ruby-core:24063]
diff --git a/hash.c b/hash.c
index 3fab523ae5..6c8fa5e0c6 100644
--- a/hash.c
+++ b/hash.c
@@ -667,6 +667,7 @@ static VALUE
rb_hash_set_default_proc(VALUE hash, VALUE proc)
{
VALUE b;
+ int n;
rb_hash_modify(hash);
b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
@@ -676,6 +677,11 @@ rb_hash_set_default_proc(VALUE hash, VALUE proc)
rb_obj_classname(proc));
}
proc = b;
+ n = rb_proc_arity(proc);
+ if (rb_proc_lambda_p(proc) && n != 2 && (n >= 0 || n < -3)) {
+ if (n < 0) n = -n-1;
+ rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
+ }
RHASH(hash)->ifnone = proc;
FL_SET(hash, HASH_PROC_DEFAULT);
return proc;
diff --git a/include/ruby/intern.h b/include/ruby/intern.h
index fa678a778b..cece6424fe 100644
--- a/include/ruby/intern.h
+++ b/include/ruby/intern.h
@@ -305,6 +305,7 @@ VALUE rb_proc_new(VALUE (*)(ANYARGS/* VALUE yieldarg[, VALUE procarg] */), VALUE
VALUE rb_proc_call(VALUE, VALUE);
VALUE rb_proc_call_with_block(VALUE, int argc, VALUE *argv, VALUE);
int rb_proc_arity(VALUE);
+VALUE rb_proc_lambda_p(VALUE);
VALUE rb_binding_new(void);
VALUE rb_obj_method(VALUE, VALUE);
VALUE rb_method_call(int, VALUE*, VALUE);
diff --git a/proc.c b/proc.c
index b7c632c856..4c2f244b81 100644
--- a/proc.c
+++ b/proc.c
@@ -223,8 +223,8 @@ proc_clone(VALUE self)
*
*/
-static VALUE
-proc_lambda_p(VALUE procval)
+VALUE
+rb_proc_lambda_p(VALUE procval)
{
rb_proc_t *proc;
GetProcPtr(procval, proc);
@@ -1971,7 +1971,7 @@ proc_curry(int argc, VALUE *argv, VALUE self)
}
else {
sarity = FIX2INT(arity);
- if (proc_lambda_p(self) && (sarity < marity || (sarity > marity && !opt))) {
+ if (rb_proc_lambda_p(self) && (sarity < marity || (sarity > marity && !opt))) {
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", sarity, marity);
}
}
@@ -2028,7 +2028,7 @@ Init_Proc(void)
rb_define_method(rb_cProc, "eql?", proc_eq, 1);
rb_define_method(rb_cProc, "hash", proc_hash, 0);
rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
- rb_define_method(rb_cProc, "lambda?", proc_lambda_p, 0);
+ rb_define_method(rb_cProc, "lambda?", rb_proc_lambda_p, 0);
rb_define_method(rb_cProc, "binding", proc_binding, 0);
rb_define_method(rb_cProc, "curry", proc_curry, -1);
rb_define_method(rb_cProc, "source_location", rb_proc_location, 0);