[ruby-core:119332] [Ruby master Feature#20769] Add `Hash#transform_value`

Issue #20769 has been reported by seanpdoyle (Sean Doyle). ---------------------------------------- Feature #20769: Add `Hash#transform_value` https://bugs.ruby-lang.org/issues/20769 * Author: seanpdoyle (Sean Doyle) * Status: Open ---------------------------------------- Add `Hash#transform_value` as a specialized, key-specific version of [Hash#transform_values](https://docs.ruby-lang.org/en/3.3/Hash.html#method-i-transform_values). ```ruby hash = { image: "https://example.com/image.jpg" } mutated_hash = hash.transform_value(:image) { |url| download(url) } hash # => { image: "https://example.com/image.jpg" } mutated_hash # => { image: File<...> } hash.transform_value!(:image) { |url| download(url) } hash # => { image: File<...> } ``` Similar value transformation can be achieved through variable assignment and direct mutation: ```ruby hash = { image: "https://example.com/image.jpg" } hash.merge(image: download(hash[:image])) hash[:image] = download(hash[:image]) ``` While simple and currently supported, it requires a local variable (and therefore poses some challenges when chaining other methods) and repeats the Hash key in both the reading and writing portions of the code. -- https://bugs.ruby-lang.org/

Issue #20769 has been updated by nobu (Nobuyoshi Nakada). ```ruby hash.merge(image: nil) {|_, url| download(url)} hash.merge!(image: nil) {|_, url| download(url)} ``` ---------------------------------------- Feature #20769: Add `Hash#transform_value` https://bugs.ruby-lang.org/issues/20769#change-109945 * Author: seanpdoyle (Sean Doyle) * Status: Open ---------------------------------------- Add `Hash#transform_value` as a specialized, key-specific version of [Hash#transform_values](https://docs.ruby-lang.org/en/3.3/Hash.html#method-i-transform_values). ```ruby hash = { image: "https://example.com/image.jpg" } mutated_hash = hash.transform_value(:image) { |url| download(url) } hash # => { image: "https://example.com/image.jpg" } mutated_hash # => { image: File<...> } hash.transform_value!(:image) { |url| download(url) } hash # => { image: File<...> } ``` Similar value transformation can be achieved through variable assignment and direct mutation: ```ruby hash = { image: "https://example.com/image.jpg" } hash.merge(image: download(hash[:image])) hash[:image] = download(hash[:image]) ``` While simple and currently supported, it requires a local variable (and therefore poses some challenges when chaining other methods) and repeats the Hash key in both the reading and writing portions of the code. -- https://bugs.ruby-lang.org/

Issue #20769 has been updated by seanpdoyle (Sean Doyle). Thank you for sharing that code sample. It demonstrates an interesting way to use `Hash#merge` with a block argument. When the key argument is absent from the Hash, a call to `Hash#transform_value` would be a no-operation. I apologize for not including this in the original example: ```ruby hash = { foo: "value" } transformed_hash = hash.transform_key(:bar) { |value| fail "This block is never yielded" } transformed_hash # => { foo: "value" } ``` nobu (Nobuyoshi Nakada) wrote in #note-1:
```ruby hash.merge(image: nil) {|_, url| download(url)}
hash.merge!(image: nil) {|_, url| download(url)} ```
Using `Hash#merge` in the way you have shared does reduce the number times the key name is repeated. However, without a guarding conditional call to `hash.key?(:image)`, the returned `Hash` would include `image: nil` when an `:image` key was not initially present: ```ruby hash = {} transformed_hash = hash.merge(image: nil) { |_, url| download(url) } transformed_hash # => { image: nil } hash = {} transformed_hash = hash.merge(image: nil) { |_, url| download(url) } if hash.key?(:image) transformed_hash # => {} ``` ---------------------------------------- Feature #20769: Add `Hash#transform_value` https://bugs.ruby-lang.org/issues/20769#change-109946 * Author: seanpdoyle (Sean Doyle) * Status: Open ---------------------------------------- Add `Hash#transform_value` as a specialized, key-specific version of [Hash#transform_values](https://docs.ruby-lang.org/en/3.3/Hash.html#method-i-transform_values). ```ruby hash = { image: "https://example.com/image.jpg" } mutated_hash = hash.transform_value(:image) { |url| download(url) } hash # => { image: "https://example.com/image.jpg" } mutated_hash # => { image: File<...> } hash.transform_value!(:image) { |url| download(url) } hash # => { image: File<...> } ``` Similar value transformation can be achieved through variable assignment and direct mutation: ```ruby hash = { image: "https://example.com/image.jpg" } hash.merge(image: download(hash[:image])) hash[:image] = download(hash[:image]) ``` While simple and currently supported, it requires a local variable (and therefore poses some challenges when chaining other methods) and repeats the Hash key in both the reading and writing portions of the code. -- https://bugs.ruby-lang.org/

Issue #20769 has been updated by matz (Yukihiro Matsumoto). Status changed from Open to Feedback I don't see the real-world use-case for the proposed method. Matz. ---------------------------------------- Feature #20769: Add `Hash#transform_value` https://bugs.ruby-lang.org/issues/20769#change-110078 * Author: seanpdoyle (Sean Doyle) * Status: Feedback ---------------------------------------- Add `Hash#transform_value` as a specialized, key-specific version of [Hash#transform_values](https://docs.ruby-lang.org/en/3.3/Hash.html#method-i-transform_values). ```ruby hash = { image: "https://example.com/image.jpg" } mutated_hash = hash.transform_value(:image) { |url| download(url) } hash # => { image: "https://example.com/image.jpg" } mutated_hash # => { image: File<...> } hash.transform_value!(:image) { |url| download(url) } hash # => { image: File<...> } ``` Similar value transformation can be achieved through variable assignment and direct mutation: ```ruby hash = { image: "https://example.com/image.jpg" } hash.merge(image: download(hash[:image])) hash[:image] = download(hash[:image]) ``` While simple and currently supported, it requires a local variable (and therefore poses some challenges when chaining other methods) and repeats the Hash key in both the reading and writing portions of the code. -- https://bugs.ruby-lang.org/
participants (3)
-
matz (Yukihiro Matsumoto)
-
nobu (Nobuyoshi Nakada)
-
seanpdoyle (Sean Doyle)