From: marcandre-ruby-core@... Date: 2021-04-16T21:05:49+00:00 Subject: [ruby-core:103489] [Ruby master Feature#17808] Feature Request: JS like splat of Object properties as named method parameters Issue #17808 has been updated by marcandre (Marc-Andre Lafortune). I believe the answers given so far should help (i.e. `(**rest)` and defining `to_hash`). Also looks into `Struct` that does some of that for you. I wish `Struct` was better for inheritance though, I'd like to propose a better solution one day. In the meantime, if this discussion needs to continue, it would be more appropriate on StackOverflow / some code-refactoring site, as there doesn't seem to be a particular feature request. ---------------------------------------- Feature #17808: Feature Request: JS like splat of Object properties as named method parameters https://bugs.ruby-lang.org/issues/17808#change-91587 * 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/ Unsubscribe: