i've been battling for two hours with this but can't solve it. Imagine i have this class:
class SimpleExpression
attr_writer :value
def initialize(value)
@value = value
end
def evaluate
@value
end
And then i want to instance it like:
exp1 = SimpleExpression.new(true)
exp3 = exp1.not
p exp3.evaluate # This should give me false
exp1.value = false
p exp3.evaluate # This should give me true now
I can't really figure out how to maintain the reference for exp1 on exp3, i've tried making a method at SimpleExpression that negates the value and returns self but that clearly does not work since i'd be changing both instances. Thanks. PS: not should be a method in SimpleExpression, i did not write it since i really do not know how to.
If it was simple "disconnected" negation, the implementation would've been simple:
def not
SimpleExpression.new(!value)
end
Here, changing exp1
does not affect exp3
.
exp1 = SimpleExpression.new(true)
exp3 = exp1.not
p exp3.evaluate # => false
exp1.value = false
p exp3.evaluate # => false
But making them "live" requires something a little bit more advanced. I'm thinking, some wrapper objects. Like this, for example:
class SimpleExpression
attr_accessor :value
def initialize(value)
@value = value
end
def evaluate
@value
end
def not
NegationWrapper.new(self)
end
private
class NegationWrapper < DelegateClass(self)
def evaluate
!__getobj__.evaluate
end
end
end
exp1 = SimpleExpression.new(true)
exp3 = exp1.not
p exp3.evaluate # => false
exp1.value = false
p exp3.evaluate # => true