proc.c: Implement Method#* for Method composition
* proc.c (rb_method_compose): Implement Method#* for Method composition, which delegates to Proc#*. * test/ruby/test_method.rb: Add test cases for Method composition. From: Paul Mucur <mudge@mudge.name> git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65912 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a43e967b8d
commit
4eaf22cc3f
25
proc.c
25
proc.c
@ -3099,6 +3099,30 @@ proc_compose(VALUE self, VALUE g)
|
|||||||
return proc;
|
return proc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* meth * g -> a_proc
|
||||||
|
*
|
||||||
|
* Returns a proc that is the composition of this method and the given proc <i>g</i>.
|
||||||
|
* The returned proc takes a variable number of arguments, calls <i>g</i> with them
|
||||||
|
* then calls this method with the result.
|
||||||
|
*
|
||||||
|
* def f(x)
|
||||||
|
* x * 2
|
||||||
|
* end
|
||||||
|
*
|
||||||
|
* f = self.method(:f)
|
||||||
|
* g = proc {|x, y| x + y }
|
||||||
|
* h = f * g
|
||||||
|
* p h.call(1, 2) #=> 6
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
rb_method_compose(VALUE self, VALUE g)
|
||||||
|
{
|
||||||
|
VALUE proc = method_to_proc(self);
|
||||||
|
return proc_compose(proc, g);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Document-class: LocalJumpError
|
* Document-class: LocalJumpError
|
||||||
*
|
*
|
||||||
@ -3222,6 +3246,7 @@ Init_Proc(void)
|
|||||||
rb_define_method(rb_cMethod, "call", rb_method_call, -1);
|
rb_define_method(rb_cMethod, "call", rb_method_call, -1);
|
||||||
rb_define_method(rb_cMethod, "===", rb_method_call, -1);
|
rb_define_method(rb_cMethod, "===", rb_method_call, -1);
|
||||||
rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
|
rb_define_method(rb_cMethod, "curry", rb_method_curry, -1);
|
||||||
|
rb_define_method(rb_cMethod, "*", rb_method_compose, 1);
|
||||||
rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
|
rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
|
||||||
rb_define_method(rb_cMethod, "arity", method_arity_m, 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);
|
||||||
|
@ -1040,4 +1040,38 @@ class TestMethod < Test::Unit::TestCase
|
|||||||
assert_operator(0.method(:<), :===, 5)
|
assert_operator(0.method(:<), :===, 5)
|
||||||
assert_not_operator(0.method(:<), :===, -5)
|
assert_not_operator(0.method(:<), :===, -5)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_compose_with_method
|
||||||
|
c = Class.new {
|
||||||
|
def f(x) x * 2 end
|
||||||
|
def g(x) x + 1 end
|
||||||
|
}
|
||||||
|
f = c.new.method(:f)
|
||||||
|
g = c.new.method(:g)
|
||||||
|
h = f * g
|
||||||
|
|
||||||
|
assert_equal(6, h.call(2))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_compose_with_proc
|
||||||
|
c = Class.new {
|
||||||
|
def f(x) x * 2 end
|
||||||
|
}
|
||||||
|
f = c.new.method(:f)
|
||||||
|
g = proc {|x| x + 1}
|
||||||
|
h = f * g
|
||||||
|
|
||||||
|
assert_equal(6, h.call(2))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_compose_with_nonproc_or_method
|
||||||
|
c = Class.new {
|
||||||
|
def f(x) x * 2 end
|
||||||
|
}
|
||||||
|
f = c.new.method(:f)
|
||||||
|
|
||||||
|
assert_raise(TypeError) {
|
||||||
|
f * 5
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user