Project

General

Profile

Feature #17336

Updated by k0kubun (Takashi Kokubun) about 4 years ago

## Problem 
 When we need a monkey patch which is used only in a single file, we'd like to define a refinement and use it in the same place. The problem is that it needs deep indentation and `Module.new { ... }` which feels redundant. 

 ```rb 
 class Foo 
   using Module.new { 
     refine Array do 
       def flat_map!(&block) 
         replace(flat_map(&block)) 
       end 
     end 
   } 
  
   # ... 
 end 
 ``` 

 @tagomoris proposed an idea to reduce indentation and remove `Module.new { ... }`. This looks pretty convenient, but I want to write `do ... end`, which would make it a block of `using` here, because we almost always use `... `do ... end` for defining methods or modules. 

 ```rb 
 module Kernel 
   def refined(mod, &block) 
     Module.new do 
       refine(mod, &block) 
     end 
   end 
 end 

 class Foo 
   using refined(Array) { 
     def flat_map!(&block) 
       replace(flat_map(&block)) 
     end 
   } 

   # ... 
 end 
 ``` 

 ## Proposal 
 How about supporting this? Because `using` currently doesn't take a block, it doesn't conflict with the existing syntax. 

 ```rb 
 class Foo 
   using refined: Array do 
     def flat_map!(&block) 
       replace(flat_map(&block)) 
     end 
   end 

   # ... 
 end 
 ``` 

 This syntax is based on ideas of @tagomoris and @znz .

Back