ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
@ 2020-04-22  6:14 takashikkbn
  2020-04-22 14:57 ` [ruby-core:98019] " merch-redmine
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: takashikkbn @ 2020-04-22  6:14 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been reported by k0kubun (Takashi Kokubun).

----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806

* Author: k0kubun (Takashi Kokubun)
* Status: Open
* Priority: Normal
----------------------------------------
## 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 some of such use cases could be considering all arguments as normal arguments when there's at least one non-keyword argument (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 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 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:98019] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
  2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
@ 2020-04-22 14:57 ` merch-redmine
  2020-04-23  6:10 ` [ruby-core:98024] " takashikkbn
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: merch-redmine @ 2020-04-22 14:57 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been updated by jeremyevans0 (Jeremy Evans).


I'm OK with the basic idea of allowing keyword init for Structs by default.  However, because this changes behavior, I think we should keep existing behavior and warn in Ruby 3.0 and not make this change until Ruby 3.1. I think this change should only affect cases where keywords are passed without positional arguments during Struct initialization.

For `Post.new(foo: "bar")`, this should still be treated as keyword init, even though foo is not a member of Post.  In Ruby 3.0, that would warn and use `{:foo=>"bar"}` as the first member of Post.  In Ruby 3.1, that would raise ArgumentError, since foo is not a member of Post and the keywords will be treated as named members.

For `Post.new(1, foo: "bar")`, `Post.new(1, name: "hello")`, `Post.new(1, id: 1)`: I think these should be treated the same as Ruby 2.  Any non-keyword argument should treat keywords as a positional hash argument.  I think allowing mixing of the arguments would result in confusion, brings up additional edge cases, and there is no practical use case for it.

Do we want to support `Post = Struct.new(:id, :name, keyword_init: false)` to disallow keyword initialization and always treat keywords as a positional hash?  I think we should as that is the intent of the code.  Basically, `keyword_init` would allow 3 values:
 
* nil: default behavior.  Positional arguments given use positional init. Keyword arguments without positional arguments treated as positional in 3.0 with warning, and treated as keyword init in Ruby 3.1.
* true: Require keyword init, disallow positional init.
* false: Treat keywords as positional hash.

----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806#change-85251

* Author: k0kubun (Takashi Kokubun)
* Status: Open
* Priority: Normal
----------------------------------------
## 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 of such use cases (continue to return `#<struct Post id=1, name={:foo=>"bar"}`) could be considering all arguments as non-keyword arguments either when there's at least one non-keyword argument (`1` 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.

### 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:98024] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
  2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
  2020-04-22 14:57 ` [ruby-core:98019] " merch-redmine
@ 2020-04-23  6:10 ` takashikkbn
  2021-01-13  6:30 ` [ruby-core:102052] " matz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: takashikkbn @ 2020-04-23  6:10 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been updated by k0kubun (Takashi Kokubun).

Description updated

I agreed with your ideas and reflected them to the description.

----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806#change-85257

* Author: k0kubun (Takashi Kokubun)
* Status: Open
* Priority: Normal
----------------------------------------
## 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(id: 1, name: "hello")` will be `#<struct Post id=1, name="hello">` instead of `#<struct Post id={:id=>1, :name=>"hello"}, name=nil>`
  * Struct initialization only using keyword arguments should be warned in Ruby 3.0. **This feature should be introduced in Ruby 3.1 or later.**

### Edge cases

* When keyword arguments and positional arguments are mixed: `Post.new(1, name: "hello")`
  * This should continue to work like Ruby 2: `#<struct Post id=1, name={:name="hello"}>`
* Only keywords are given but they include an invalid member: `Post.new(foo: "bar")`
  * ArgumentError (unknown keywords: foo)
* When `keyword_init` is used
  * nil: default behavior. Positional arguments given use positional init. Keyword arguments without positional arguments treated as positional in 3.0 with warning, and treated as keyword init in Ruby 3.1.
  * true: Require keyword init, disallow positional init.
  * false: Treat keywords as positional hash.

## 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 deal with the "Known incompatibility".
  * 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:102052] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
  2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
  2020-04-22 14:57 ` [ruby-core:98019] " merch-redmine
  2020-04-23  6:10 ` [ruby-core:98024] " takashikkbn
@ 2021-01-13  6:30 ` matz
  2021-01-19  0:05 ` [ruby-core:102147] " takashikkbn
  2022-01-29  8:29 ` [ruby-core:107343] " k0kubun (Takashi Kokubun)
  4 siblings, 0 replies; 6+ messages in thread
From: matz @ 2021-01-13  6:30 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been updated by matz (Yukihiro Matsumoto).


I am OK with 3.1 to warn, 3.2 to change.

Matz.


----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806#change-89908

* Author: k0kubun (Takashi Kokubun)
* Status: Open
* Priority: Normal
----------------------------------------
## 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(id: 1, name: "hello")` will be `#<struct Post id=1, name="hello">` instead of `#<struct Post id={:id=>1, :name=>"hello"}, name=nil>`
  * Struct initialization only using keyword arguments should be warned in Ruby 3.0. **This feature should be introduced in Ruby 3.1 or later.**

### Edge cases

* When keyword arguments and positional arguments are mixed: `Post.new(1, name: "hello")`
  * This should continue to work like Ruby 2: `#<struct Post id=1, name={:name="hello"}>`
* Only keywords are given but they include an invalid member: `Post.new(foo: "bar")`
  * ArgumentError (unknown keywords: foo)
* When `keyword_init` is used
  * nil: default behavior. Positional arguments given use positional init. Keyword arguments without positional arguments treated as positional in 3.0 with warning, and treated as keyword init in Ruby 3.1.
  * true: Require keyword init, disallow positional init.
  * false: Treat keywords as positional hash.

## 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 deal with the "Known incompatibility".
  * 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:102147] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
  2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
                   ` (2 preceding siblings ...)
  2021-01-13  6:30 ` [ruby-core:102052] " matz
@ 2021-01-19  0:05 ` takashikkbn
  2022-01-29  8:29 ` [ruby-core:107343] " k0kubun (Takashi Kokubun)
  4 siblings, 0 replies; 6+ messages in thread
From: takashikkbn @ 2021-01-19  0:05 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been updated by k0kubun (Takashi Kokubun).

Assignee set to k0kubun (Takashi Kokubun)
Status changed from Closed to Assigned

----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806#change-89999

* Author: k0kubun (Takashi Kokubun)
* Status: Assigned
* Priority: Normal
* Assignee: k0kubun (Takashi Kokubun)
----------------------------------------
## 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(id: 1, name: "hello")` will be `#<struct Post id=1, name="hello">` instead of `#<struct Post id={:id=>1, :name=>"hello"}, name=nil>`
  * Struct initialization only using keyword arguments should be warned in Ruby 3.0. **This feature should be introduced in Ruby 3.1 or later.**

### Edge cases

* When keyword arguments and positional arguments are mixed: `Post.new(1, name: "hello")`
  * This should continue to work like Ruby 2: `#<struct Post id=1, name={:name="hello"}>`
* Only keywords are given but they include an invalid member: `Post.new(foo: "bar")`
  * ArgumentError (unknown keywords: foo)
* When `keyword_init` is used
  * nil: default behavior. Positional arguments given use positional init. Keyword arguments without positional arguments treated as positional in 3.0 with warning, and treated as keyword init in Ruby 3.1.
  * true: Require keyword init, disallow positional init.
  * false: Treat keywords as positional hash.

## 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 deal with the "Known incompatibility".
  * 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:107343] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default
  2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
                   ` (3 preceding siblings ...)
  2021-01-19  0:05 ` [ruby-core:102147] " takashikkbn
@ 2022-01-29  8:29 ` k0kubun (Takashi Kokubun)
  4 siblings, 0 replies; 6+ messages in thread
From: k0kubun (Takashi Kokubun) @ 2022-01-29  8:29 UTC (permalink / raw)
  To: ruby-core

Issue #16806 has been updated by k0kubun (Takashi Kokubun).

Status changed from Assigned to Closed

@nobu already committed the last step at commit:c956f979e5d05900315d2753d5c3b1389af8dae4. Closing.

----------------------------------------
Feature #16806: Struct#initialize accepts keyword arguments too by default
https://bugs.ruby-lang.org/issues/16806#change-96240

* Author: k0kubun (Takashi Kokubun)
* Status: Closed
* Priority: Normal
* Assignee: k0kubun (Takashi Kokubun)
----------------------------------------
## 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(id: 1, name: "hello")` will be `#<struct Post id=1, name="hello">` instead of `#<struct Post id={:id=>1, :name=>"hello"}, name=nil>`
  * Struct initialization only using keyword arguments should be warned in Ruby 3.0. **This feature should be introduced in Ruby 3.1 or later.**

### Edge cases

* When keyword arguments and positional arguments are mixed: `Post.new(1, name: "hello")`
  * This should continue to work like Ruby 2: `#<struct Post id=1, name={:name="hello"}>`
* Only keywords are given but they include an invalid member: `Post.new(foo: "bar")`
  * ArgumentError (unknown keywords: foo)
* When `keyword_init` is used
  * nil: default behavior. Positional arguments given use positional init. Keyword arguments without positional arguments treated as positional in 3.0 with warning, and treated as keyword init in Ruby 3.1.
  * true: Require keyword init, disallow positional init.
  * false: Treat keywords as positional hash.

## 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 deal with the "Known incompatibility".
  * 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.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-01-29  8:29 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-22  6:14 [ruby-core:98014] [Ruby master Feature#16806] Struct#initialize accepts keyword arguments too by default takashikkbn
2020-04-22 14:57 ` [ruby-core:98019] " merch-redmine
2020-04-23  6:10 ` [ruby-core:98024] " takashikkbn
2021-01-13  6:30 ` [ruby-core:102052] " matz
2021-01-19  0:05 ` [ruby-core:102147] " takashikkbn
2022-01-29  8:29 ` [ruby-core:107343] " k0kubun (Takashi Kokubun)

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).