Project

General

Profile

Feature #18644

Updated by waiting_for_dev (Marc Busqué) over 2 years ago

Functional objects are increasingly popular in Ruby. Having objects that respond to `#call` makes them interchangeable with a `Proc`. 

 However, when you need to perform some Proc-specific operation, like currying, you have to break the abstraction and ask for the type of object. Example: 

 ```ruby 
 (callable.is_a?(Proc) ? callable : callable.method(:call)).curry[value] 
 ``` 

 Because of https://bugs.ruby-lang.org/issues/18620, it's not possible to make them polymorphic by taking the `:call` method: 

 ```ruby 
 callable.method(:call).curry[value] # won't work! 
 ``` 

 Consequently, I propose adding a built-in Ruby way to coerce anything callable to a proc (examples in Ruby): 

 ### Option 1: `Object#to_proc` 

 ```ruby 
 class Object 
   def to_proc 
     return method(:call).to_proc if respond_to?(:call) 
  
     raise "Needs to respond to :call" 
   end 
 end 

 class Proc 
   def to_proc 
     self 
   end 
 end 

 callable.to_proc.curry[value] 
 ``` 

 ### Option 2. `Kernel#Proc` `Kernel.Proc` 

 ```ruby 
 class Kernel 
   def Proc(value) 
     if value.is_a?(::Proc) 
       value 
     elsif value.respond_to?(:call) 
       value.method(:call).to_proc 
     else 
       raise "Needs to implement :call" 
     end 
   end 
 end 

 Proc(callable).curry[value] 
 ```

Back