Ruby Superclass Mismatch, Structs and Unicorn
05 Mar 2016Recently, I have found an Unicorn deployment bug that raised my attention on how Ruby’s native Struct
object is implemented and how different is using its declaration APIs.
Usually, when we are declaring Structs on our algorithms, we (naively) write this:
The interesting aspect of this kind of declaration is that Struct.new
inheritance will always instantiate a new class!
In other words, if your application server is using the hot reload feature (preload_app
flag turned to true), you’ll be seeing the following error on your next deploy:
This error is not so explicit about what’s going on behind the scenes. The fact that Struct.new
is actually creating a new class every time it’s running, and different parts of your code are trying to redundantly declare a class with a different parent, isn’t so clear when the superclass mismatch
error is raised upon the Struct.new
inheritance!
Example:
Doesn’t look like a superclass mismatch, does it?
Solution
Instead of using the inheritance syntax, use the constant attribution syntax:
This way, you won’t have any issues with super classes, and your constant will behave exactly like you first intended, without raising any errors!
If you are curious to see how this is actually implemented on Ruby core, I recommend you to read the source code on the
Struct::new
docs. You’ll see that the block version instantiates an anonymous struct to any variable you like.