Created
December 9, 2014 14:01
-
-
Save plexus/42c6c9c63212182ee440 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# How to update values on immutable objects? | |
class Foo | |
def initialize(attrs) | |
@x = attrs.fetch(:x) | |
@y = attrs.fetch(:y) | |
freeze | |
end | |
end | |
foo = Foo.new(x: 5, y: 7) | |
# Option 0 | |
# Use x=9. Would be great but doesn't work in Ruby, it will always | |
# return it's argument so you can chain assignments | |
# Option 1 | |
class Foo | |
attr_reader :x, :y | |
def set_x(x) | |
self.class.new(x: x, y: y) | |
end | |
end | |
foo.set_x(9) # => #<Foo:0x007fbe1e7acc48 @x=9, @y=7> | |
foo # => #<Foo:0x007fbe1e7acd60 @x=5, @y=7> | |
# Option 2 | |
Undefined = Object.new | |
def Undefined.inspect ; 'Undefined' ; end | |
class Foo | |
def x(x = Undefined) | |
if x == Undefined | |
@x | |
else | |
self.class.new(x: x, y: @y) | |
end | |
end | |
end | |
foo.x(9) # => #<Foo:0x007fbe1e7ac4c8 @x=9, @y=7> | |
foo # => #<Foo:0x007fbe1e7acd60 @x=5, @y=7> | |
# Option 3 | |
# Same as #1, but with_x, apparently common in Scala/Java | |
# Option 4 | |
# Anima style, use explicit "update" function | |
require 'anima' | |
class Foo | |
include Anima.new(:x, :y) | |
include Anima::Update | |
end | |
foo.update(x: 9) # => #<Foo x=9 y=7> | |
foo # => #<Foo x=5 y=7> | |
# Option 5 | |
# ... | |
# Any other ideas? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Great to get so many replies on this! It seems some people also name their
update
/copy
/with
methodnew
. I've seen this and think I might have actually used it at some point, although I'm not a fan because it's different enough from the class method new to cause confusion.