From: "marcotc (Marco Costa)" Date: 2021-09-29T21:16:45+00:00 Subject: [ruby-core:105495] [Ruby master Feature#12719] `Struct#merge` for partial updates Issue #12719 has been updated by marcotc (Marco Costa). To add a real-world use-case: in the [`ddtrace gem`](https://github.com/DataDog/dd-trace-rb) we have a [configuration Struct called `AgentSettings`](https://github.com/DataDog/dd-trace-rb/blob/b1bd0c025e26d47508996c0b7928fcc366cc0fad/lib/ddtrace/configuration/agent_settings_resolver.rb#L22-L42) that holds the global defaults for our configuration: ``` ruby AgentSettings = Struct.new( :ssl, :hostname, :port, :timeout_seconds, :deprecated_for_removal_transport_configuration_proc, :deprecated_for_removal_transport_configuration_options ) do def initialize( ssl:, hostname:, port:, timeout_seconds:, deprecated_for_removal_transport_configuration_proc:, deprecated_for_removal_transport_configuration_options:, ) super(ssl, hostname, port, timeout_seconds, deprecated_for_removal_transport_configuration_proc, \ deprecated_for_removal_transport_configuration_options) freeze end end ``` But in a few places we want to [override some of the default configuration values](https://github.com/DataDog/dd-trace-rb/blob/e391d2eb64d3c6151a4bdd2710c6a8c7c1d57457/lib/ddtrace/profiling/transport/http.rb#L76-L81): ```ruby transport.adapter( default_adapter, agent_settings.hostname, agent_settings.port, # We explicitly use profiling_upload_timeout_seconds instead of agent_settings.timeout because profile # uploads are bigger and thus we employ a separate configuration. timeout: profiling_upload_timeout_seconds, ssl: agent_settings.ssl ) ``` Today we resort to unpacking the Struct and effectively transferring the values to a hash (in the form of keyword arguments). We don't actually want our Struct to become a hash (or keyword arguments) when we pass it to `#adapter` in the example above, we would like a `AgentSettings` struct to be passed but with `timeout` overridden. ---------------------------------------- Feature #12719: `Struct#merge` for partial updates https://bugs.ruby-lang.org/issues/12719#change-93944 * Author: halogenandtoast (Matthew Mongeau) * Status: Feedback * Priority: Normal ---------------------------------------- Other languages have operators for performing partial updates on maps. I feel like Struct could be more useful if it provided an easy way of performing partial (or full) updates. After the change you can do the following: ~~~ ruby Point = Struct.new(:x, :y) p = Point.new(1, 2) p2 = p.merge(y: 4) p3 = p2.merge(x: 10) p.inspect # => # p2.inspect # => # p3.inspect # => # p.merge!("x" => 9) p.inspect # => # ~~~ ---Files-------------------------------- struct_merge.patch (2.93 KB) -- https://bugs.ruby-lang.org/ Unsubscribe: