Implement Proc#* and Method#* for Proc and Method composition - #935
Implement Proc#* and Method#* for Proc and Method composition#935mudge wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
If we could change this to send call to g with the given arguments (e.g. via rb_funcall), this would work with any object with a call method (including other Procs, Methods and regular Ruby classes).
Alternatively, we could ensure g is a Proc by calling to_proc on it if it is not already a Proc (not entirely dissimilar to using the existing StringValue macro).
As discussed on the issue tracker, this would mean the difference between the following Ruby pseudocode:
# Where g must only implement call
class Proc
def *(g)
proc { |*args, &blk| call(g.call(*args, &blk)) }
end
endvs
# Where g must only implement to_proc
class Proc
def *(g)
proc { |*args, &blk| call(g.to_proc.call(*args, &blk)) }
end
end|
I, for one, would love to see this merged! :) |
|
I like the idea of functional composition but I don't like the implementation here. First of all, I don't like naming it And the second problem that it does not deal well with custom callable objects. I mean: module Increment
def self.call(x)
x + 1
end
end
multiply_two = proc { |x| x * 2 }
(multiply_two * Increment).call(1) # => 4
(Increment * multiply_two).call(1) # => NoMethodErrorSo, I like the concept of mixin with composition operator more like it's done in module Increment
extend PipelineOperator
def self.call(x)
x + 1
end
end |
* proc.c (proc_compose): Implement Proc#* for Proc composition, enabling composition of Procs and Methods. [Feature #6284] * test/ruby/test_proc.rb: Add test cases for Proc 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.
* proc.c (proc_compose): support any object with a call method rather than supporting only procs. [Feature #6284] * proc.c (compose): use the function call on the given object rather than rb_proc_call_with_block in order to support any object. * test/ruby/test_proc.rb: Add test cases for composing Procs with callable objects. * test/ruby/test_method.rb: Add test cases for composing Methods with callable objects.
|
FWIW I am pro |
|
It seems to have a conflict now. Could you rebase this from master? |
|
Oh, I see. Thank you 👍 |
c.f. https://bugs.ruby-lang.org/issues/6284
Allow
Procs andMethods to be composed together with*.Support composition with any object that has a
callmethod, e.g.This implementation should be largely equivalent to the following Ruby (excepting that the
lambda?property is preserved):