Project

General

Profile

Feature #20318

Updated by bradgessler (Brad Gessler) 9 months ago

 
 # Premise 

 Sometimes when I'm creating a method for an API, I'd like to do pattern matching against the arguments. Today I have to do something like this: 

 ```ruby 
 def foo(*args, **kwargs, &block) 
   case { args:, kwargs:, args: args, kwargs: kwargs, block: block } 
     in args: [name] 
       puts name 
     in args: [first_name, last_name] 
       puts "Hi there #{first_name} #{last_name}" 
     in kwargs: {greeting:} 
       puts "Hello #{greeting}" 
     else 
       puts "No match: #{args}" 
   end 
 end 

 foo "Hi" 
 foo "Brad", "Gessler" 
 foo greeting: "Brad" 
 ``` 

 Or an array like this: 

 ```ruby 
 def bar(*args, **kwargs, &block) 
   case [args, kwargs, block] 
     in [name], {}, nil 
       puts name 
     in [first_name, last_name], {}, nil 
       puts "Hi there #{first_name} #{last_name}" 
     in [], {greeting:}, nil 
       puts "Hello #{greeting}" 
     else 
       puts "No match: #{args}, #{kwargs}" 
   end 
 end 

 bar "Howdy" 
 bar "Bradley", "Gessler" 
 bar greeting: "Bradley" 
 ``` 

 # Proposal 

 I'd like to propose the same thing, but for `...`, like this: 

 ```ruby 
 def foo(...) 
   case ... 
     in args: [name] 
       puts name 
     in args: [first_name, last_name] 
       puts "Hi there #{first_name} #{last_name}" 
     in kwargs: {greeting:} 
       puts "Hello #{greeting}" 
     else 
       puts "No match: #{args}" 
   end 
 end 

 foo "Hi" 
 foo "Brad", "Gessler" 
 foo greeting: "Brad" 
 ``` 

 One thing I'm not sure sure about: the `args`, `kwargs`, and `block` names appear out of thin air, so ideally those could somehow be named or have a syntax that doesn't require those names. 

 The array would look like this: 

 ```ruby 
 def bar(...) 
   case ... 
     in [name], {}, nil 
       puts name 
     in [first_name, last_name], {}, nil 
       puts "Hi there #{first_name} #{last_name}" 
     in [], {greeting:}, nil 
       puts "Hello #{greeting}" 
     else 
       puts "No match: #{args}, #{kwargs}" 
   end 
 end 

 bar "Howdy" 
 bar "Bradley", "Gessler" 
 bar greeting: "Bradley" 
 ```

Back