How to override a variable in a Ruby subclass without affecting the superclass?

Say I have a class with several “static” variables. I want a subclass of this class to be able to override these variables without affecting the original class. This is not possible using class variables, as they appear to be shared between subclasses and superclasses:

class Foo @@test = "a" def speak; puts @@test; end end class Bar < Foo @@test = "b" end Bar.new.speak # b Foo.new.speak # b 

Cannot use constants:

 class Foo TEST = "a" def speak; puts TEST; end end class Bar < Foo TEST = "b" end Bar.new.speak # a Foo.new.speak # a 

Methods defined in the superclass ignore constants in the subclass.

An obvious workaround is to define methods for variables that must be "redefined":

 class Foo def test; "a"; end end 

But that sounds like a hack. I feel that this should be possible using class variables and that I'm probably just doing it wrong. For example, when I subclass Object (which happens by default):

 class Foo < Object @@bar = 123 end Object.class_variable_get(:@@bar) # NameError: uninitialized class variable @@bar in Object 

Why is @@bar not set to Object , as it was in my example Bar < Foo above?


To summarize: how to override a variable in a subclass without affecting the superclass?

+6
source share
3 answers

Class constants do what you want, you just need to use them in different ways:

 class Foo TEST = "a" def speak puts self.class::TEST end end class Bar < Foo TEST = "b" end Bar.new.speak # => a Foo.new.speak # => b 
+5
source

Add the variable to the class itself (as in the class instance, not in the class variable):

 class Foo @var = 'A' class << self attr_reader :var end def var self.class.var end end class Bar < Foo @var = 'B' end Foo.var # A Foo.new.var # A Bar.var # B Bar.new.var # B 
+4
source

The correct way (IMHO) is to use methods, because in this way you use inheritance and virtual dispatch as you want.

Class variables are passed in a hierarchy, not up. Therefore, @@bar not available in Object .

+2
source

Source: https://habr.com/ru/post/955987/


All Articles