From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-Status: No, score=-2.6 required=3.0 tests=AWL,BAYES_00, DKIM_ADSP_CUSTOM_MED,FORGED_GMAIL_RCVD,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED shortcircuit=no autolearn=no autolearn_force=no version=3.4.2 Received: from neon.ruby-lang.org (neon.ruby-lang.org [221.186.184.75]) by dcvr.yhbt.net (Postfix) with ESMTP id A7A1A1F66E for ; Sat, 29 Aug 2020 12:29:32 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 4B145120AAD; Sat, 29 Aug 2020 21:28:52 +0900 (JST) Received: from xtrwkhkc.outbound-mail.sendgrid.net (xtrwkhkc.outbound-mail.sendgrid.net [167.89.16.28]) by neon.ruby-lang.org (Postfix) with ESMTPS id 8DA88120970 for ; Sat, 29 Aug 2020 21:28:49 +0900 (JST) Received: by filterdrecv-p3las1-75ccf54874-d4svb with SMTP id filterdrecv-p3las1-75ccf54874-d4svb-18-5F4A4A19-3 2020-08-29 12:29:13.111933524 +0000 UTC m=+152962.557647567 Received: from herokuapp.com (unknown) by ismtpd0038p1iad2.sendgrid.net (SG) with ESMTP id 26TQSTTLRrCvJnaNzntZSw for ; Sat, 29 Aug 2020 12:29:12.915 +0000 (UTC) Date: Sat, 29 Aug 2020 12:29:13 +0000 (UTC) From: sawadatsuyoshi@gmail.com Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 75602 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 13683 X-Redmine-Issue-Author: dnagir X-Redmine-Sender: sawa X-Mailer: Redmine X-Redmine-Host: bugs.ruby-lang.org X-Redmine-Site: Ruby Issue Tracking System X-Auto-Response-Suppress: All Auto-Submitted: auto-generated X-SG-EID: =?us-ascii?Q?jFXA8Rt481sXUUIO9tYW1AJlMOZdNdlSw=2F5TfLCefGt=2FR=2FsRt52gXXVKWlARsG?= =?us-ascii?Q?6kCCGqVuRFjZq6IANNmBGC7zgaxmbeoEvDDR0nw?= =?us-ascii?Q?3X6B6RUrYqODXi8QnfVHDuPxGIRDF8jioUyJmro?= =?us-ascii?Q?au=2FpV5egfYVk9U1+w0Frhj=2FRTHXlTn7W6uMk48e?= =?us-ascii?Q?ld5cj2zRiQ38AmPj5CVPggCn+3H=2Fm=2FJ3KjYyXss?= =?us-ascii?Q?oSd5st7rh2KZKKzRA=3D?= To: ruby-core@ruby-lang.org X-ML-Name: ruby-core X-Mail-Count: 99770 Subject: [ruby-core:99770] [Ruby master Feature#13683] Add strict Enumerable#single X-BeenThere: ruby-core@ruby-lang.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: Ruby developers List-Id: Ruby developers List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ruby-core-bounces@ruby-lang.org Sender: "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/