ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:99757] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
@ 2020-08-28 20:19 ` fatkodima123
  2020-08-28 21:14 ` [ruby-core:99758] " marcandre-ruby-core
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: fatkodima123 @ 2020-08-28 20:19 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by fatkodima (Dima Fatko).


I have opened a PR - https://github.com/ruby/ruby/pull/3470

```
# Returns one and only one item. Raises an error if there are none or more than one.
[99].one            #=> 99
[].one              #=> RuntimeError: collection is empty
[99, 100].one       #=> RuntimeError: collection contains more than one item

# If collection is empty and no block was given, returns default value:
[].one(99)          #=> 99

# If collection is empty and a block was given, returns the block's return value:
[].one { 99 }       #=> 99
```

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87261

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99758] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
  2020-08-28 20:19 ` [ruby-core:99757] [Ruby master Feature#13683] Add strict Enumerable#single fatkodima123
@ 2020-08-28 21:14 ` marcandre-ruby-core
  2020-08-29  4:23 ` [ruby-core:99765] " sawadatsuyoshi
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: marcandre-ruby-core @ 2020-08-28 21:14 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by marcandre (Marc-Andre Lafortune).


If we introduce `one`, it would be nice to support regexp; maybe use `===` for matching when given an argument?

```ruby
%w[hello world].one(/ll/) # => 'hello'
```


----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87262

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99765] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
  2020-08-28 20:19 ` [ruby-core:99757] [Ruby master Feature#13683] Add strict Enumerable#single fatkodima123
  2020-08-28 21:14 ` [ruby-core:99758] " marcandre-ruby-core
@ 2020-08-29  4:23 ` sawadatsuyoshi
  2020-08-29 11:11 ` [ruby-core:99768] " daniel
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: sawadatsuyoshi @ 2020-08-29  4:23 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by sawa (Tsuyoshi Sawada).


Having `Enumerable#find` take an optional keyword argument, say `exception:`, would make more sense, is useful and have more generality.

```ruby
[1].find(strict: true){true} # => 1
[1, 2, 3].find(exception: true){true} # >> Error
[].find(exception: true){true} # >> Error
%w[hello world].find(exception: true){/ll/ === _1} # => "hello"
%w[hello world].find(exception: true){/l/ === _1} # => Error
%w[hello world].find(exception: true){/x/ === _1} # => Error
```



----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87274

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99768] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2020-08-29  4:23 ` [ruby-core:99765] " sawadatsuyoshi
@ 2020-08-29 11:11 ` daniel
  2020-08-29 12:29 ` [ruby-core:99770] " sawadatsuyoshi
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: daniel @ 2020-08-29 11:11 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by Dan0042 (Daniel DeLorme).


> If collection is empty and a block was given, returns the block's return value:

I really think the block form should be like find/select

```ruby
[1,2,3].one{ _1.even? }        #=> 2
[1,2,3,4].one{ _1.even? }      #=> error
[1,2,3,4].one(nil){ _1.even? } #=> nil
```

> Having `Enumerable#find` take an optional keyword argument, say `exception:`, would make more sense, be useful, and have more generality.

I don't think so; find only returns the first element found. An argument that makes it continue searching and return an exception if it finds a second match... that alters the fundamental behavior too much imho.

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87280

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99770] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2020-08-29 11:11 ` [ruby-core:99768] " daniel
@ 2020-08-29 12:29 ` sawadatsuyoshi
  2020-08-29 12:42 ` [ruby-core:99772] " daniel
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: sawadatsuyoshi @ 2020-08-29 12:29 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by sawa (Tsuyoshi Sawada).


Dan0042 (Daniel DeLorme) wrote in #note-25: 
> I really think the block form should be like find/select
> 
> ```ruby
> [1,2,3].one{ _1.even? }        #=> 2
> [1,2,3,4].one{ _1.even? }      #=> error
> [1,2,3,4].one(nil){ _1.even? } #=> nil
> ```
...
> continue searching [...] that alters the fundamental behavior too much imho.

I think you are right.

I think the English word that best matches the concept is the definite article. This word presupposes that there is exactly one corresponding entity in the context, and picks that entity. If the presupposition is not satisfied, then the entire expression would be uninterpretable in the case of natural languages, which amounts to raising an exception in the case of programming languages.

```ruby
[1,2,3].the{_1.even?} # => 2
[1,2,3,4].the{_1.even?} # >> error
```

Using the usual block parameter, `[1,2,3].the{|x| x.even?}` could be read as "**the** `x` (out of `[1, 2, 3]`) such that `x` is even." If such `x` does not uniquely exist, this expression is uninterpretable.

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87282

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99772] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2020-08-29 12:29 ` [ruby-core:99770] " sawadatsuyoshi
@ 2020-08-29 12:42 ` daniel
  2020-08-30 11:26 ` [ruby-core:99778] " eregontp
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: daniel @ 2020-08-29 12:42 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by Dan0042 (Daniel DeLorme).


Hmmm, just now I realized there's a simple idiom that's roughly equivalent to `one`

```ruby
[1,2].inject{break} #=> nil
[1,2].inject{raise} #=> error
[1].inject{break}   #=> 1
[1].inject{raise}   #=> 1
[].inject{break}    #=> nil
[].inject{raise}    #=> nil (instead of error)
```


----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87284

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:99778] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (5 preceding siblings ...)
  2020-08-29 12:42 ` [ruby-core:99772] " daniel
@ 2020-08-30 11:26 ` eregontp
  2020-09-15  6:35 ` [ruby-core:100008] " shannonskipper
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: eregontp @ 2020-08-30 11:26 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by Eregon (Benoit Daloze).


matz (Yukihiro Matsumoto) wrote in #note-10:
> Hmm, I don't like the name `single`.

matz (Yukihiro Matsumoto) wrote in #note-17:
> I don't like `only` either since these names do not describe the behavior.

Could you explain why?
I think `single` as in "return a single element or error out" is the best name here, and the most intuitive.
If I want a random element, then #sample already exists, so I don't think there would be any confusion to what `Array#single` or `Enumerable#single` would do.

`array.only` reads weirdly to me. `array.single` is so much nicer, no?

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87293

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100008] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (6 preceding siblings ...)
  2020-08-30 11:26 ` [ruby-core:99778] " eregontp
@ 2020-09-15  6:35 ` shannonskipper
  2020-09-18 20:25 ` [ruby-core:100044] " petrik
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: shannonskipper @ 2020-09-15  6:35 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by shan (Shannon Skipper).


How about #sole since it means one and only and is concise?

``` ruby
[].sole
#!> SoleError: empty Array when single value expected (contains 0, expected 1)

Set.new.sole
#!> SoleError: empty Set when single value expected (contains 0, expected 1)

[41, 42, 43].sole
#!> SoleError: too many values in Array when just one expected (contains 3, expected 1)

[42].sole
#=> 42
```

Or #one_and_only, but it's more wordy.

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87559

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100044] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (7 preceding siblings ...)
  2020-09-15  6:35 ` [ruby-core:100008] " shannonskipper
@ 2020-09-18 20:25 ` petrik
  2020-09-25  7:12 ` [ruby-core:100128] " nobu
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: petrik @ 2020-09-18 20:25 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by p8 (Petrik de Heus).


What about:

One([1])
[1].to_one

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87594

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100128] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (8 preceding siblings ...)
  2020-09-18 20:25 ` [ruby-core:100044] " petrik
@ 2020-09-25  7:12 ` nobu
  2020-09-25  7:14 ` [ruby-core:100129] " mame
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: nobu @ 2020-09-25  7:12 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by nobu (Nobuyoshi Nakada).


Dan0042 (Daniel DeLorme) wrote in #note-25:
> > If collection is empty and a block was given, returns the block's return value:
> 
> I really think the block form should be like find/select
> 
> ```ruby
> [1,2,3].one{ _1.even? }        #=> 2
> [1,2,3,4].one{ _1.even? }      #=> error
> [1,2,3,4].one(nil){ _1.even? } #=> nil
> ```

It looks close to `Enumerable#one?` which counts truthy values only, but has a different semantics.


----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87697

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100129] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (9 preceding siblings ...)
  2020-09-25  7:12 ` [ruby-core:100128] " nobu
@ 2020-09-25  7:14 ` mame
  2020-10-02 14:14 ` [ruby-core:100280] " nobu
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 14+ messages in thread
From: mame @ 2020-09-25  7:14 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by mame (Yusuke Endoh).


A practical use case: When scraping a HTML document or something, sometimes we assume that an array length is 1.

```
nodes = html_node.children.select {|node| node.name == "table" }
raise if nodes.size == 1
the_node_i_want = nodes.first
```

The `raise` is needed for the case where my assumption is wrong.

This proposal makes it a bit helpful:

```
the_node_i_want = html_node.children.select {|node| node.name == "table" }.sole
```

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87698

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100280] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (10 preceding siblings ...)
  2020-09-25  7:14 ` [ruby-core:100129] " mame
@ 2020-10-02 14:14 ` nobu
  2020-10-06 21:06 ` [ruby-core:100316] " shannonskipper
  2021-09-02 17:52 ` [ruby-core:105124] " meisel (Michael Eisel)
  13 siblings, 0 replies; 14+ messages in thread
From: nobu @ 2020-10-02 14:14 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by nobu (Nobuyoshi Nakada).


What about pattern matching?

```ruby
case []; in [a]; p a; end #=> NoMatchingPatternError ([])
case [1]; in [a]; p a; end #=> 1
case [1,2]; in [a]; p a; end #=> NoMatchingPatternError ([1, 2])
```

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87866

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:100316] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (11 preceding siblings ...)
  2020-10-02 14:14 ` [ruby-core:100280] " nobu
@ 2020-10-06 21:06 ` shannonskipper
  2021-09-02 17:52 ` [ruby-core:105124] " meisel (Michael Eisel)
  13 siblings, 0 replies; 14+ messages in thread
From: shannonskipper @ 2020-10-06 21:06 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by shan (Shannon Skipper).


``` ruby
[42] in [sole]; sole     #=> 42
[] in [sole]; sole       #!> NoMatchingPatternError ([])
[42, 43] in [sole]; sole #!> NoMatchingPatternError ([42, 43])
```

For Arrays, pattern matching seems reasonable. Wouldn't that not work for other Enumerable collections?

``` ruby
Set.new([42]) in [sole]; sole #!> NoMatchingPatternError (#<Set: {42}>)
```

It seems it an Enumerable# method would be more slick and nice for method chaining.

``` ruby
Set.new([42]).sole #=> 42
Set.new([42]).sole.digits #=> [2, 4]
```


----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-87897

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

* [ruby-core:105124] [Ruby master Feature#13683] Add strict Enumerable#single
       [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
                   ` (12 preceding siblings ...)
  2020-10-06 21:06 ` [ruby-core:100316] " shannonskipper
@ 2021-09-02 17:52 ` meisel (Michael Eisel)
  13 siblings, 0 replies; 14+ messages in thread
From: meisel (Michael Eisel) @ 2021-09-02 17:52 UTC (permalink / raw)
  To: ruby-core

Issue #13683 has been updated by meisel (Michael Eisel).


+1 for this, I've needed it in many cases, generally where I have to select an element from a set and there's no stable/documented way of doing this. So, I find some criteria that seem to work, but would like to protect against my criteria being wrong or invalidated by future changes. In the past, I've needed it for sets like sibling directories and sibling XML nodes.

As for the name, I think `#take_only` would be another reasonable option

----------------------------------------
Feature #13683: Add strict Enumerable#single
https://bugs.ruby-lang.org/issues/13683#change-93537

* Author: dnagir (Dmytrii Nagirniak)
* Status: Feedback
* Priority: Normal
----------------------------------------
### Summary

This is inspired by other languages and frameworks, such as LINQ's [Single](https://msdn.microsoft.com/en-us/library/bb155325%28v=vs.110%29.aspx) (pardon MSDN reference), which has very big distinction between `first` and `single` element of a
collection.

- `first` normally returns the top element, and the developer assumes
  there could be many;
- `single` returns one and only one element, and it is an error if there
  are none or more than one.

We, in Ruby world, very often write `fetch_by('something').first`
assuming there's only one element that can be returned there.

But in majority of the cases, we really want a `single` element.

The problems with using `first` in this case:

- developer needs to explicitly double check the result isn't `nil`
- in case of corrupted data (more than one item returned), it will never
  be noticed

`Enumerable#single` addresses those problems in a very strong and
specific way that may save the world by simply switching from `first` to
`single`.

### Other information

- we may come with a better internal implementation (than `self.map`)
- better name could be used, maybe `only` is better, or a bang version?
- re-consider the "block" implementation in favour of a separate method (`single!`, `single_or { 'default' }`)


The original implementation is on the ActiveSupport https://github.com/rails/rails/pull/26206
But it was suggested to discuss the possibility of adding it to Ruby which would be amazing.



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

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

end of thread, other threads:[~2021-09-02 17:52 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <redmine.issue-13683.20170627060807.1663@ruby-lang.org>
2020-08-28 20:19 ` [ruby-core:99757] [Ruby master Feature#13683] Add strict Enumerable#single fatkodima123
2020-08-28 21:14 ` [ruby-core:99758] " marcandre-ruby-core
2020-08-29  4:23 ` [ruby-core:99765] " sawadatsuyoshi
2020-08-29 11:11 ` [ruby-core:99768] " daniel
2020-08-29 12:29 ` [ruby-core:99770] " sawadatsuyoshi
2020-08-29 12:42 ` [ruby-core:99772] " daniel
2020-08-30 11:26 ` [ruby-core:99778] " eregontp
2020-09-15  6:35 ` [ruby-core:100008] " shannonskipper
2020-09-18 20:25 ` [ruby-core:100044] " petrik
2020-09-25  7:12 ` [ruby-core:100128] " nobu
2020-09-25  7:14 ` [ruby-core:100129] " mame
2020-10-02 14:14 ` [ruby-core:100280] " nobu
2020-10-06 21:06 ` [ruby-core:100316] " shannonskipper
2021-09-02 17:52 ` [ruby-core:105124] " meisel (Michael Eisel)

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