class A < T::Enum
enums do
Foo = new('foo')
Bar = new('bar')
end
sig {returns(T::Boolean)}
def is_good?
case self
when Foo then true
when Bar then false
else T.absurd(self)
end
end
end
x = A::Foo
y = Marshal.load(Marshal.dump(A::Foo))
x.is_good? # true
A::Foo === x # true
A::Foo === y # false
y.is_good? # raises as it reached T.absurd(self)
This is problematic because when parallelizing Ruby scripts with multiple-processes, object passing is achieved through serializing the object using Marshal, piping it down to the destination process, then deserializing it using Marshal again.
Currently, the definition of === for T::Enum is super(other). I propose changing it to super(other) || (self.class == other.class && self.serialize == other.serialize).
However, I realized that there could be other design decisions to be made beyond this.
Another possible solution is to change the Marshal custom serialization/deserialization instead:
def _dump(level)
serialize
end
def self._load(args)
deserialize(args)
end
Thanks for the workaround with this, @julius-stripe!
We're experiencing this as well. Can we update this to a bug instead of an enhancement?
Fixed in #3206
Most helpful comment
Thanks for the workaround with this, @julius-stripe!
We're experiencing this as well. Can we update this to a bug instead of an enhancement?