-
Notifications
You must be signed in to change notification settings - Fork 26
Open
Description
If I create an object that has a memowised value, then .dup to clone that object, the resulting duped object seems to share the same cache entry as the original object. Then these two objects have some sort of invisible coupling.
Example:
require "memo_wise"
class MyTest
prepend MemoWise
def initialize(value)
@value = value
end
attr_reader :value
def computed_value = 2 * @value
memo_wise :computed_value
def increment
@value += 1
reset_memo_wise
end
end
original = MyTest.new(5)
puts original.value # Outputs 5
puts original.computed_value # Outputs 10
duped = original.dup
puts duped.value # Outputs 5
puts duped.computed_value # Outputs 10
# should just reset duped's memowise cache, but resets both
duped.increment
# calling computed_value on duped will update the cached computed_value for both objects
puts duped.value # Outputs 6
puts duped.computed_value # Outputs 12
puts original.value # Outputs 5
puts original.computed_value # X - Outputs 12 instead of 10Similar example, in reverse order
require "memo_wise"
class MyTest
prepend MemoWise
def initialize(value)
@value = value
end
attr_reader :value
def computed_value = 2 * @value
memo_wise :computed_value
def increment
@value += 1
reset_memo_wise
end
end
original = MyTest.new(5)
puts original.value # Outputs 5
puts original.computed_value # Outputs 10
duped = original.dup
puts duped.value # Outputs 5
puts duped.computed_value # Outputs 10
# should just reset duped's memowise cache, but resets both
duped.increment
# calling computed_value on original will update the cached computed_value for both objects
puts original.value # Outputs 5
puts original.computed_value # Outputs 10
puts duped.value # Outputs 6
puts duped.computed_value # X - Outputs 10 instead of 12Example with mutable cached value
Here, duped keeps the same exact object instance cached for computed_value, so modifications done to either will be visible in both.
I would have expected that duped's memowise cache would start empty, and allow it to build its own computed_value.
require "memo_wise"
class MyTest
prepend MemoWise
def initialize(value)
@value = value
end
attr_reader :value
def computed_value = { "value" => @value }
memo_wise :computed_value
end
original = MyTest.new(5)
puts original.value # Outputs 5
puts original.computed_value # Outputs {"value"=>5}
duped = original.dup
puts duped.value # Outputs 5
puts duped.computed_value # Outputs {"value"=>5}
duped.computed_value["value"] += 1
puts duped.value # Outputs 5
puts duped.computed_value # Outputs {"value"=>6}
puts original.value # Outputs 5
puts original.computed_value # X - Outputs {"value"=>6} instead of {"value"=>5}
puts duped.computed_value.object_id == original.computed_value.object_id # Outputs true which is IMO unexpectedTested with 1.13.0
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels