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=-3.8 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY shortcircuit=no autolearn=ham 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 D6C1B1F4B4 for ; Wed, 21 Oct 2020 13:29:04 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 6C43E120A36; Wed, 21 Oct 2020 22:28:18 +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 D74421209D5 for ; Wed, 21 Oct 2020 22:28:15 +0900 (JST) Received: by filterdrecv-p3las1-68f969d758-sbfq7 with SMTP id filterdrecv-p3las1-68f969d758-sbfq7-19-5F903793-1B 2020-10-21 13:28:51.313733959 +0000 UTC m=+45789.451189604 Received: from herokuapp.com (unknown) by geopod-ismtpd-3-7 (SG) with ESMTP id 4bkqBKcFRIiATGaIT31bNw for ; Wed, 21 Oct 2020 13:28:51.047 +0000 (UTC) Date: Wed, 21 Oct 2020 13:28:51 +0000 (UTC) From: daniel@dan42.com Message-ID: References: Mime-Version: 1.0 X-Redmine-MailingListIntegration-Message-Ids: 76344 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 17145 X-Redmine-Issue-Author: marcandre X-Redmine-Sender: Dan0042 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?8sy4RigFvRTdBfCVJrT9zb2J88PC92TMQwdNgaWYaq5qlFTMBWp13tHbyPAsj0?= =?us-ascii?Q?kpY38Jkgq=2FvOVRbuhjR4YbKqq5QRajS3WzZYme0?= =?us-ascii?Q?++tUQ6u42KECKkCbrNNhKLElqXfrt4158kLqAbB?= =?us-ascii?Q?3ygZp6bj5WzoTjRCyUo13ElY4sd1QABdDW2sDUY?= =?us-ascii?Q?tpHt9uSVhhwIBtvu2iqE8LIi8ystIkxoVio1lhK?= =?us-ascii?Q?Rzu2TfPHdLScO=2FlJk=3D?= To: ruby-core@ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== X-ML-Name: ruby-core X-Mail-Count: 100474 Subject: [ruby-core:100474] [Ruby master Feature#17145] Ractor-aware `Object#deep_freeze` 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 #17145 has been updated by Dan0042 (Daniel DeLorme). marcandre (Marc-Andre Lafortune) wrote in #note-22: > I've been wanting for a long while to propose an API for caching methods, and that could be made Ractor compatible and would resolve most of these cases, but maybe it's too early to consider it? +1 The `@var ||= expr` idiom works well for most cases of memoization, but breaks down for nil values and frozen objects. It's easy enough to handle these cases with a small memoization library (and in fact I do so in my code). But since frozen objects are now going to be everywhere because of ractor, I think it's time to introduce this in core. ---------------------------------------- Feature #17145: Ractor-aware `Object#deep_freeze` https://bugs.ruby-lang.org/issues/17145#change-88093 * Author: marcandre (Marc-Andre Lafortune) * Status: Open * Priority: Normal ---------------------------------------- I'd like to propose `Object#deep_freeze`: Freezes recursively the contents of the receiver (by calling `deep_freeze`) and then the receiver itself (by calling `freeze`). Values that are shareable via `Ractor` (e.g. classes) are never frozen this way. ```ruby # freezes recursively: ast = [:hash, [:pair, [:str, 'hello'], [:sym, :world]]].deep_freeze ast.dig(1, 1) # => [:str, 'hello'] ast.dig(1, 1).compact! # => FrozenError # does not freeze classes: [[String]].deep_freeze String.frozen? # => false # calls `freeze`: class Foo def freeze build_cache! puts "Ready for freeze" super end # ... end [[[Foo.new]]].deep_freeze # => Outputs "Ready for freeze" ``` I think a variant `deep_freeze!` that raises an exception if the result isn't Ractor-shareable would be useful too: ```ruby class Fire def freeze # do not call super end end x = [Fire.new] x.deep_freeze! # => "Could not be deeply-frozen: #" ``` -- https://bugs.ruby-lang.org/