Project

General

Profile

Feature #16806

Updated by k0kubun (Takashi Kokubun) 4 months ago

## Proposal 

 ```rb 
 Post = Struct.new(:id, :name) 

 # In addition to this, 
 Post.new(1, "hello") #=> #<struct Post id=1, name="hello"> 

 # Let the following initialization also work 
 Post.new(id: 1, name: "hello") #=> #<struct Post id=1, name="hello"> 
 ``` 

 ### Known incompatibility 

 * `Post.new(1, foo: "bar")` which was written in Ruby 2 will behave differently 
   * One way to save most some of such use cases (continue to return `#<struct Post id=1, name={:foo=>"bar"}`) could be considering all arguments as non-keyword normal arguments either when there's at least one non-keyword argument (`1` (continue to return `#<struct Post id=1, name={:foo=>"bar"}`). 
   * There's no way to save `Post.new(id: 1, foo: "bar")` which was written in this example) or when non-member keyword argument is specified (`foo:` in this example).  
      * This is actually confusing when using keyword arguments intentionally, and it should probably print warnings if we adopt it. Ruby 2, but I think it's fair enough to assume people would not do such misreading initialization. 

 ### Edge cases 

 * `Post.new(1, name: "hello")`: Should it behave like Ruby 2 or raise ArgumentError? (no strong preference) 
 * `Post.new(1, id: 1)`: Should it behave like Ruby 2, print warnings (setting `id=1, name=nil`) or raise ArgumentError? (no strong preference) 
 * `Post.new(1, "hello")` when `keyword_init: true` is explicitly set: It should continue to be ArgumentError. 

 ## Use cases 

 * Simplify a struct definition where [Feature #11925] is used. 
   * When we introduced [Feature #11925], @mame thought we don't need `keyword_init: true` once keyword args are separated (https://docs.google.com/document/d/1XbUbch8_eTqh21FOwj9a_X-ZyJyCBjxkq8rWwfpf5BM/edit#). That's what this ticket is all about. 
      * However, the keyword arguments separation was done differently from what we expected at the moment. So we need to accept the "Known incompatibility". Ruby 3.0 completing the separation would be the best timing to introduce this incompatibility if we'd like this feature. 
   * Matz objected to having a new keyword argument (`immutable: true`) in `Struct.new` at https://bugs.ruby-lang.org/issues/16769#note-8. So `keyword_init: true` seems also against Ruby's design. Now we should be able to skip specifying the option for consistency in the language design.

Back