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-ASN: AS4713 221.184.0.0/13 X-Spam-Status: No, score=-2.6 required=3.0 tests=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 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 6E3B71F4B4 for ; Fri, 16 Apr 2021 19:24:45 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 41C97120D39; Sat, 17 Apr 2021 04:23:38 +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 01EDE120B31 for ; Sat, 17 Apr 2021 04:23:35 +0900 (JST) Received: by filterdrecv-7bbb56ff7b-592s6 with SMTP id filterdrecv-7bbb56ff7b-592s6-14-6079E46F-4 2021-04-16 19:24:31.065369883 +0000 UTC m=+82883.405213505 Received: from herokuapp.com (unknown) by geopod-ismtpd-5-2 (SG) with ESMTP id K--dY6oUQ-6D2v1vBzNYrA for ; Fri, 16 Apr 2021 19:24:30.988 +0000 (UTC) Date: Fri, 16 Apr 2021 19:24:31 +0000 (UTC) From: brad.krane@gmail.com Message-ID: References: Mime-Version: 1.0 X-Redmine-Project: ruby-master X-Redmine-Issue-Tracker: Feature X-Redmine-Issue-Id: 17808 X-Redmine-Issue-Author: Lithium X-Redmine-Sender: Lithium 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-Redmine-MailingListIntegration-Message-Ids: 79534 X-SG-EID: =?us-ascii?Q?FvhWrK=2FKh1p7pblJjOfXJGZRA5opuAZhak5m2QB5NT5LUqRhc+EyYdDGY8lnaR?= =?us-ascii?Q?DxV7pM=2F7D5zCqvhcqXx5kWVVlkVW9IFX5kdzgYk?= =?us-ascii?Q?YSvSXwtFRwrKVwlOd+LQQR0Ve8U9eFpvuGAF0Ga?= =?us-ascii?Q?I+QM+EzAVtqhHK2F5YC51M9SgTQW4+Yn0RNrZDm?= =?us-ascii?Q?ls+n4r1777AnIzzYVDYCxDshj8s2Unnh5Tw=3D=3D?= To: ruby-core@ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== X-ML-Name: ruby-core X-Mail-Count: 103487 Subject: [ruby-core:103487] [Ruby master Feature#17808] Feature Request: JS like splat of Object properties as named method parameters 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 #17808 has been updated by Lithium (Brad Krane). byroot (Jean Boussier) wrote in #note-3: > Well, the ruby equivalent to your example JS function would be: > > ```ruby > def test(param1: nil, param2: nil, **) > end > ``` > > The `**` will catch any key that don't match any of the declared keyword arguments. This does work, but this requires modifying all methods to include this extra parameter to avoid the error. Is there a way to modify existing declared methods adding that parameter so as to avoid an error when additional params are provided in error due to the object having more instance_variables for whatever reason? I can't see how to escape the following syntax for this functionality without heavy lifting: `other_splat(a_dog, method: method(:some_method))` With the Kernel.to_hash monkey patching how can one avoid the argument error for 'poorly written methods' that don't have the extra ** that already? There is also the case an object is passed to many different methods all with different named params selectively grabbing what's needed for the moment, without having to mod all the methods to have a **, or specifying a specific to_hash_some_method for each method or using `other_splat(a_dog, method: method(:some_method))` which does work but is ugly af for Ruby in my opinion. ---------------------------------------- Feature #17808: Feature Request: JS like splat of Object properties as named method parameters https://bugs.ruby-lang.org/issues/17808#change-91585 * Author: Lithium (Brad Krane) * Status: Open * Priority: Normal ---------------------------------------- I'm pretty sure there is no equivalent Ruby for a very convenient JS way to enter named function parameters as below: ``` javascript const test = ({param1, param2, param3 = null, param4 = false, param5 = null, }={}) => { console.log(`${param1}, ${param2}, ${param3}, ${param4}, ${param5}\n`) } let obj = { param1: 23, param2: 234, param3: 235, param4: 257 }; test({...obj}); ``` which is super convenient and as far as I'm aware there is no standard Ruby equivalent. It can be accomplished in Ruby but the call syntax is far less nice. A couple examples below: ``` ruby # Implementing such a feature wouldn't be too difficult. # Ok so here is what you could do it. Patch Kernel with a method splat. (Sorry in advance for formatting) module Kernel def splat obj, method: new_hash = method.parameters.reduce({}) do |hash, attrr| hash[attrr.last] = obj.send(attrr.last) hash end end end # Then you can pass it a list of symbols. # Then for your method: def some_method name:, weight: puts "#{name} weighs #{weight}" end class Dog attr_reader :name, :weight def initialize name:,weight: @name = name @weight = weight end end a_dog = Dog.new( name: 'fido', weight: '7kg') hash_puppy = a_dog.splat(a_dog, method: method(:some_method) ) some_method(**hash_puppy) ``` or what I think is a bit better: ``` ruby # Same class as above a_dog = Dog.new( name: 'fido', weight: '7kg') def other_splat obj, method: new_hash = method.parameters.reduce({}) do |hash, attrr| if obj.class <= Hash hash[attrr.last] = obj[attrr.last] else hash[attrr.last] = obj.send attrr.last end hash end method.call **new_hash end other_splat(a_dog, method: method(:some_method)) # above line should be like: # some_method ...a_dog ``` Source: https://gist.github.com/bradkrane/e051d205024a5313cb4a5b9eb1eae0e3 I'm sure I'm missing a possibly more clever way to accomplish this, but I'm pretty sure something like `other_splat(a_dog, method: method(:some_method))` is about as close as it can get, unless I'm missing something? It would be quite nice to have a similar syntax as JS but in Ruby: `some_method ...a_dog` Thanks for your time and attention! -- https://bugs.ruby-lang.org/