aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-10 06:01:32 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-01-10 06:01:32 +0000
commit33a75edd3cf6062796043ae75747b4b191db3789 (patch)
treeec79ebc0c2e3b8fe14a7b410702211464fa6c08e
parent671ef4e9e3d8cb3c397547934902a6a4fd312816 (diff)
downloadruby-33a75edd3cf6062796043ae75747b4b191db3789.tar.gz
proc.c: check if callable
* proc.c: check the argument at composition, expect a Proc, Method, or callable object. [ruby-core:90591] [Bug #15428] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66769 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--proc.c37
-rw-r--r--test/ruby/test_method.rb4
-rw-r--r--test/ruby/test_proc.rb4
3 files changed, 37 insertions, 8 deletions
diff --git a/proc.c b/proc.c
index c09e845ec0..c24c0b3023 100644
--- a/proc.c
+++ b/proc.c
@@ -3063,6 +3063,21 @@ compose(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
return rb_funcallv(f, idCall, 1, &fargs);
}
+static VALUE
+to_callable(VALUE f)
+{
+ VALUE mesg;
+
+ if (rb_obj_is_proc(f)) return f;
+ if (rb_obj_is_method(f)) return f;
+ if (rb_obj_respond_to(f, idCall, TRUE)) return f;
+ mesg = rb_fstring_lit("callable object is expected");
+ rb_exc_raise(rb_exc_new_str(rb_eTypeError, mesg));
+}
+
+static VALUE rb_proc_compose_to_left(VALUE self, VALUE g);
+static VALUE rb_proc_compose_to_right(VALUE self, VALUE g);
+
/*
* call-seq:
* prc << g -> a_proc
@@ -3078,6 +3093,12 @@ compose(VALUE dummy, VALUE args, int argc, VALUE *argv, VALUE passed_proc)
static VALUE
proc_compose_to_left(VALUE self, VALUE g)
{
+ return rb_proc_compose_to_left(self, to_callable(g));
+}
+
+static VALUE
+rb_proc_compose_to_left(VALUE self, VALUE g)
+{
VALUE proc, args, procs[2];
rb_proc_t *procp;
int is_lambda;
@@ -3111,6 +3132,12 @@ proc_compose_to_left(VALUE self, VALUE g)
static VALUE
proc_compose_to_right(VALUE self, VALUE g)
{
+ return rb_proc_compose_to_right(self, to_callable(g));
+}
+
+static VALUE
+rb_proc_compose_to_right(VALUE self, VALUE g)
+{
VALUE proc, args, procs[2];
rb_proc_t *procp;
int is_lambda;
@@ -3148,8 +3175,9 @@ proc_compose_to_right(VALUE self, VALUE g)
static VALUE
rb_method_compose_to_left(VALUE self, VALUE g)
{
- VALUE proc = method_to_proc(self);
- return proc_compose_to_left(proc, g);
+ g = to_callable(g);
+ self = method_to_proc(self);
+ return proc_compose_to_left(self, g);
}
/*
@@ -3171,8 +3199,9 @@ rb_method_compose_to_left(VALUE self, VALUE g)
static VALUE
rb_method_compose_to_right(VALUE self, VALUE g)
{
- VALUE proc = method_to_proc(self);
- return proc_compose_to_right(proc, g);
+ g = to_callable(g);
+ self = method_to_proc(self);
+ return proc_compose_to_right(self, g);
}
/*
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 5cfcdb8dc5..82a1b71d32 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -1088,10 +1088,10 @@ class TestMethod < Test::Unit::TestCase
}
f = c.new.method(:f)
- assert_raise(NoMethodError) {
+ assert_raise(TypeError) {
(f << 5).call(2)
}
- assert_raise(NoMethodError) {
+ assert_raise(TypeError) {
(f >> 5).call(2)
}
end
diff --git a/test/ruby/test_proc.rb b/test/ruby/test_proc.rb
index 8e8f719892..4abe0aa1bb 100644
--- a/test/ruby/test_proc.rb
+++ b/test/ruby/test_proc.rb
@@ -1474,10 +1474,10 @@ class TestProc < Test::Unit::TestCase
def test_compose_with_noncallable
f = proc {|x| x * 2}
- assert_raise(NoMethodError) {
+ assert_raise(TypeError) {
(f << 5).call(2)
}
- assert_raise(NoMethodError) {
+ assert_raise(TypeError) {
(f >> 5).call(2)
}
end