Project

General

Profile

Feature #16460

Updated by harrisonb (Harrison Bachrach) 11 months ago

Hello! This is my first time filing an issue and I was unable to find anything similar. I apologize if one already exists. 

 In other languages (such as JavaScript, Swift, and Crystal), it is possible to have two names for a given keyword argument: one that is used in method invocation, and one used in the method definition. Here is an example from Crystal (which has syntax very similar to Ruby): 

 ```crystal 
 def increment(value, by amount) 
   value + amount 
 end 

 increment(value: 5, by: 10) 
 ``` 

 This helps create more readable method invocations and definitions. It would be especially helpful in Ruby as the language lacks a destructuring syntax for hashes/keyword args. This is unlike JavaScript, where you can do something like: 

 ```javascript 
 const { nameOfOneProperty: newNameForTheProperty, nameOfAnotherProperty: newNameForTheOtherProperty } = foo; 
 ``` 

 where `foo` is a JavaScript Object that has the properties `nameOfOneProperty` or `nameOfAnotherProperty` (If it did not have either of them, the corresponding identifiers (newNameForTheProperty and newNameForTheOtherProperty would be initialized to undefined). 

 I'm thinking that such a change would pair nicely with the new 3.0 keyword argument changes. 

 Others have A suggested that this could also syntax might be helpful if the keyword params collide with reserved keywords in Ruby, e.g.: 

 ```ruby 
 def reserve_appointment(when:) 
   Appointment.create(time: when) #=> SyntaxError: unexpected `when', expecting `end' 
 end 
 ``` 

 Currently, one must use `local_variable_get` to get around this issue, e.g.: 

 ```ruby 
 def reserve_appointment(when:) 
   time = local_variable_get(:when) 
   Appointment.create(time: time) 
 end 
 ``` 

 --- 

 ## Syntax options: 

 1. No arrow syntax (original proposal) 
 ```ruby 
 def name(external_name internal_name: default_value) internal_name:) 
   # ... 
 end 
 # Example 
 def move(from source: 'src/', to destination: 'dist/', at time:) 
   # ... 
 end 
 ``` 

 1. Infix arrow syntax 
 ```ruby 
 def name(external_name => internal_name: default_value) 
   # ... 
 end 
 # Example 
 def move(from => source: 'src/', to => destination: 'dist/', at => time:) 
   # ... 
 end 
 ``` 

 1. Postfix arrow syntax (suggested by zverok (Victor Shepelev)) 
 ```ruby 
 def name(external_name: default_value => internal_name) 
   # ... 
 end 
 # Example 
 def move(from: 'src/' => source, to: 'dist/' => destination, at: => time) 
   # ... 
 end 
 ```

Back