Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.Sign up
Class variable in subclass is not overtaken by class variable in superclass #1554
I was experimenting with class variables and I noticed that JRuby's class variables behave differently than MRI's. If a class variable is defined in a superclass after one of its subclasses already has a class variable of the same name, MRI detects the situation and merges the two variables into one. JRuby does not detect it, and it lets the class variable have a different value in the subclass and parent class.
Here is a simple script to demonstrate the difference:
class A end class B < A @@cv = :cvb def cvb @@cv end end class A @@cv = :cva end p B.new.cvb
Here is shell output showing how JRuby prints
Here is shell output showing how MRI prints a warning and then prints
(Sorry if this is a duplicate; I searched through the names of all open issues but not closed ones.)
After looking at the MRI logic, I do not believe this is a good behavior. However I'm on the fence about fixing it.
The logic in MRI appears to work as follows:
As a result, reading a class variable from a class could cause that class's value for that variable to be deleted if some other class later wrote the class variable at a higher level. The logic for this basically is backwards: the higher class always takes priority over the lower class. MRI deletes on get because it has no ability to check child classes for the same class variable.
In order to support this, we'd need to be doing the hierarchy search on every get and set (gross). We might be able to improve this if we walk down-hierarchy on set to clear out values in descendants, since then all sets would go to the highest already-set level, and gets would just walk up and find that level.
Basically the logic of having class variables override each other from above requires some serious gymnastics in the type hierarchy, while simultaneously making class variables significantly slower (since you have to search hierarchy every time no matter what).
What a stupid feature.