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=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 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 B93821F4B4 for ; Fri, 16 Apr 2021 21:01:08 +0000 (UTC) Received: from neon.ruby-lang.org (localhost [IPv6:::1]) by neon.ruby-lang.org (Postfix) with ESMTP id 220D5120E5A; Sat, 17 Apr 2021 06:00:02 +0900 (JST) Received: from o1678948x4.outbound-mail.sendgrid.net (o1678948x4.outbound-mail.sendgrid.net [167.89.48.4]) by neon.ruby-lang.org (Postfix) with ESMTPS id AEA15120DFD for ; Sat, 17 Apr 2021 05:59:59 +0900 (JST) Received: by filterdrecv-7cd54bd647-t9j52 with SMTP id filterdrecv-7cd54bd647-t9j52-15-6079FB05-CB 2021-04-16 21:00:53.61438559 +0000 UTC m=+88769.322224708 Received: from herokuapp.com (unknown) by geopod-ismtpd-2-0 (SG) with ESMTP id _UIjOMD9QkSBRw6zdeVlYg for ; Fri, 16 Apr 2021 21:00:53.600 +0000 (UTC) Date: Fri, 16 Apr 2021 21:00:53 +0000 (UTC) From: jean.boussier@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: byroot 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: 79535 X-SG-EID: =?us-ascii?Q?AchqQMoUBMcQgz7gop0XiYUiatGIY7E61JGsTL4FvjcZ4GR9eR7k1yZ3fkydOn?= =?us-ascii?Q?W5GbsSCv13zG83CfHLB8IjaZxJGaYAKZy=2FdQSN4?= =?us-ascii?Q?EiA3FfcnAPuGgJ5p=2FYJ93i=2FPrkjYSpZWlHrsdEm?= =?us-ascii?Q?fqO7rSnre1Q6eUSZF2YoUJ6KiNKgLCmkNtkjn4q?= =?us-ascii?Q?u52nEt4OnHhT3hAt2ouJUwhpaWcBIqQG8ObZKFt?= =?us-ascii?Q?htWXLlADGCang0W1E=3D?= To: ruby-core@ruby-lang.org X-Entity-ID: b/2+PoftWZ6GuOu3b0IycA== X-ML-Name: ruby-core X-Mail-Count: 103488 Subject: [ruby-core:103488] [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 byroot (Jean Boussier). > Is there a way to modify existing declared methods adding that parameter Well, I suppose you can decorate the methods and filter the extra keywords, a bit tricky but doable: ```ruby class Module def ignore_extra_parameters(method_name) method = instance_method(method_name) keyword_args = method.parameters.filter_map { |type, name| name if type == :key || type == :keyreq } define_method(method_name) do |*args, **kwargs, &block| method.bind_call(self, *args, **kwargs.slice(*keyword_args), &block) end end end class MyObject def initialize(bar) @bar = bar end def to_hash { bar: @bar, plop: 42 } end end module Test extend self ignore_extra_parameters def foo(bar:) p bar end end Test.foo(**MyObject.new(42)) # => 42 ``` But ultimately your whole feature request rely on a very specific JS "feature" (many people would call it a cruft), that extra arguments are simply ignored. That's not the case in Ruby, every argument must be accounted for. And while I'm merely an observer of the ruby-core development, I'm pretty sure it isn't acceptable to change. So I doubt there any way such feature would be implemented. Or you'd need to introduce some new syntax for the caller to specify that the extra parameters should be discarded, but again, not very likely to happen. ---------------------------------------- Feature #17808: Feature Request: JS like splat of Object properties as named method parameters https://bugs.ruby-lang.org/issues/17808#change-91586 * 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/