Project

General

Profile

Feature #12719

`Struct#merge` for partial updates

Added by halogenandtoast (Matthew Mongeau) over 2 years ago. Updated over 2 years ago.

Status:
Feedback
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:77125]

Description

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:

Point = Struct.new(:x, :y)

p = Point.new(1, 2)
p2 = p.merge(y: 4)
p3 = p2.merge(x: 10)

p.inspect     # => #<struct Point x=1, y=2>
p2.inspect   # => #<struct Point x=1, y=4>
p3.inspect   # => #<struct Point x=10, y=4>

p.merge!("x" => 9)

p.inspect    # => #<struct Point x=9, y=2>

Files

struct_merge.patch (2.93 KB) struct_merge.patch halogenandtoast (Matthew Mongeau), 09/05/2016 02:55 AM

History

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • Tracker changed from Bug to Feature

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

If this is well received I think a similar syntax could be used for hashes in place of merge.

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File struct_merge.patch added

As an alternative since the | syntax might get shot down. Here's a patch adding a merge function instead:

Point = Struct.new(:x, :y)

p = Point.new(1, 2)
p2 = p.merge(y: 4)
p3 = p2.merge(x: 10)

puts p.inspect # => #<struct Point x=1, y=2>
puts p2.inspect # => #<struct Point x=1, y=4>
puts p3.inspect # => #<struct Point x=10, y=4>

Updated by nobu (Nobuyoshi Nakada) over 2 years ago

In your example, the value in the LHS is ignored when the same key is present in the RHS hash.
It doesn't feel nice as | operator.

merge sounds nice in that sense, but your patch would segfault at p.merge(0).

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

Thanks, nice catch. I'll update this tomorrow to not segfault.

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File struct_merge_no_segfault.patch added

Updated so it won't segfault

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File merge_bang.patch added

Since merge closely resembles the similar hash function, I think it makes sense to also add merge! as a function. I'm not a fan of the mutating methods, but I would find it surprising if this interface was different. Here's an updated patch. I also fixed some of the documentation I wrote.

#8

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File deleted (struct_update.patch)
#9

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File deleted (struct_merge.patch)
#10

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File deleted (struct_merge_no_segfault.patch)

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

Update ChangeLog

#12

Updated by halogenandtoast (Matthew Mongeau) over 2 years ago

  • File deleted (merge_bang.patch)

Updated by matz (Yukihiro Matsumoto) over 2 years ago

  • Status changed from Open to Feedback

I want to see a real-world use-case for the feature.
In addition, I don't think the name merge is the best for the functionality.

Matz.

Updated by Eregon (Benoit Daloze) over 2 years ago

Scala has "copy" for this purpose: some_case_class_object.copy(field: new_value)

Also available in: Atom PDF