From: "zverok (Victor Shepelev) via ruby-core" Date: 2024-10-23T07:57:18+00:00 Subject: [ruby-core:119595] [Ruby master Feature#15381] Let double splat call `to_h` implicitly Issue #15381 has been updated by zverok (Victor Shepelev). > I think that would be awesome. If I do `other_method(**model)` and that model is representable as a hash, passing it as keyword arguments is beautiful. ...until you passed it erroneously, and it was never meant to be, and the error happened not where it should happen but in some completely different place. ...until somebody tries to make heads or tails from the legacy codebase and assumes that something that is invoked with `**value` is hash-like, while in fact, it was a value object, and there is no way to know it without chasing it back and forth by call stack. Now, _imagine_ if that was the author���s intention (���here we unpack our model into the keyword args���) and the author just wrote (like, five more characters) ```ruby other_method(**model.to_h) ``` ...and the reader immediately sees where the ���transition point��� is from value object/model to keyword args/hash-like data. > Imagine something like > ```ruby > ValidOptions = Struct.new(:ssl, :host, :port) > ``` Now imagine that if you want to have such options as kwarg-passable, you can just ```ruby ValidOptions = Struct.new(:ssl, :host, :port) { alias to_hash to_h } ``` ...and that immediately communicates ���this particular value object (unlike many other value objects) thinks of it as a hash-like object that would be unpacked probably at some point���. >> problem of things being unintentionally unpacked, considering how many objects have to_h method > > That never happens. I have never ever written code where `foo(**opts)` throws "no implicit conversion of Object into Hash" and then I realize I really meant to use something other than opts. I saw this a lot (especially transitioning from older to newer syntaxes, libraries, and Ruby versions). Fighting anecdata with anecdata! :) The conversion from ���it had just one extra parameter��� to ���it has a hash of extra parameters��� is a frequent refactoring when some library matures, and I really like to have it reported to me early that some object passed where it doesn���t correspond to the target method���s expectations. `NoMethodError`/���no implicit conversion��� is a wonderful tool for this, but only if it happens _in the closest place to the possible error_. PS: Honestly, I am still not sure which _problem_ we are trying to solve (that is not covered by the `**nil` addition) that is so frequent and has no other easy solution to be worth all the drawbacks. ---------------------------------------- Feature #15381: Let double splat call `to_h` implicitly https://bugs.ruby-lang.org/issues/15381#change-110217 * Author: sawa (Tsuyoshi Sawada) * Status: Open ---------------------------------------- The single splat calls `to_a` implicitly on the object (if it is not an array already) so that, for example, we have the convenience of writing conditions in an array literal: ```ruby a = [ *(:foo if some_condition), *(:bar if another_condition), ] ``` And the ampersand implicitly calls `to_proc` on the object (if it is not a proc already) so that we can substitute a block with an ampersand followed by a symbol: ```ruby some_method(&:some_method_name) ``` Unlike the single splat and ampersand, the double splat does not seem to implicitly call a corresponding method. I propose that the double splat should call `to_h` implicitly on the object if it not already a Hash so that we can, for example, write a condition in a hash literal as follows: ```ruby h = { **({a: 1} if some_condition), **({b: 2) if another_condition), } ``` There may be some other benefits of this feature that I have not noticed yet. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/