2

Example:

class Base
  @@var = "base"

  def self.assign_var(var)
    @@var = var
  end

  def self.show_var
    @@var
  end

  def initialize
    p @@var
  end

end

class A < Base
  assign_var("a")
end

class B < Base
  assign_var("b")
end

class C < Base
  assign_var("c")
end

p A.show_var # "c"
p B.show_var # "c"
p C.show_var # "c"
a = A.new # "c"
b = B.new # "c"
c = C.new # "c"

How to make them to show their own value assigned in their class? like this:

p A.show_var # "a"
p B.show_var # "b"
p C.show_var # "c"
a = A.new # "a"
b = B.new # "b"
c = C.new # "c"

UPDATE

I need to access this var in the initializer.

class Base
  @var = "base"

  def self.assign_var(var)
    @var = var
  end

  def self.show_var
    @var
  end

  def initialize
    p @var
  end
end

class A < Base
  assign_var("a")
end

class B < Base
  assign_var("b")
end

class C < Base
  assign_var("c")
end

p A.show_var # "a"
p B.show_var # "b"
p C.show_var # "c"
a = A.new # nil
b = B.new # nil
c = C.new # nil

If I use Vu's solution, it is not working... Any ideas?

2 Answers 2

5

Class variable is not redefined in subclasses. You can use class level instance variable in this case:

class Base
  @var = "base"

  def self.assign_var(var)
    @var = var
  end

  def self.show_var
    @var
  end
end

class A < Base
  assign_var("a")
end

class B < Base
  assign_var("b")
end

class C < Base
  assign_var("c")
end

p A.show_var # "a"
p B.show_var # "b"
p C.show_var # "c"

For more information: http://www.railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

Sign up to request clarification or add additional context in comments.

1 Comment

Some docs call a class variable (@@) a class hierarchy variable, because for this reason. I never saw a good example when to use a class hierarchy variable. IMO the rule of thumb is: Do not use them.
2

Please treat the following as an extended comment on @Vu's answer. He gave a good answer (+1), but intentionally kept close to the OP's code. I would merely like to point out that the usual way of doing this would be to use class instance variables (as Vu has done) and accessors for those variables:

class Base
  @var = "base"
  class << self
    attr_accessor :var
  end
end

class A < Base
  @var = "a"
end

class B < Base
  self.var = "b"
end

Base.methods(false)      #=> [:var, :var=]
A.methods(false)         #=> []
A.methods.include?(:var) #=> true
A.method(:var=)          #=> #<Method: A(Base)
A.method(:var).owner     #=> #<Class:Base>

Base.instance_variables  #=> [:@var]
A.instance_variables     #=> [:@var]

Base.var #=> "base"
A.var    #=> "a"
B.var    #=> "b"
Base.var = 'cat'
Base.var #=> "cat"
A.var    #=> "a"

1 Comment

I can see B::var being a class var as it refers to self, which means it refers to the base's var accessor, but A::@var is a class var? So you're saying that if I have an instance var and it coincides with the base class's class var that it will be silently be changed to a class var? Whoa! That's messed up!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.