Class attribute unique to subclasses but used in parent clas

Hello,

I’m new in the Ruby World and I have a question.

Let’s say I have a class with a class attribute (I call this class
Parent), this class attribute is used in instance methods of Parent.
Parent class has many subsclasses. Each subsclass should have it’s own
value of the class attribute.

Example:

class Parent
@@test = nil

def Parent.create(value)
@@test=value
new
end

def print_test
puts @@test
end
end

class Child1 < Parent
end

class Child2 < Parent
end

c1 = Parent.create ‘1’
c1.print_test # => 1
c2 = Parent.create ‘2’
c2.print_test # => 2
c1.print_test # => 2

What I’ll like, is that Child1 and Child2 have their own values of
@@test, but @@test should be initialized and used in Parent.
Also, @@test cannot be an instance variable because it is heavy to
initialize and will be common to all instances of Child1 or Child2.

Thank you

Hi –

On Sat, 28 Oct 2006, [email protected] wrote:

end
c2 = Parent.create ‘2’
c2.print_test # => 2
c1.print_test # => 2

What I’ll like, is that Child1 and Child2 have their own values of
@@test, but @@test should be initialized and used in Parent.
Also, @@test cannot be an instance variable because it is heavy to
initialize and will be common to all instances of Child1 or Child2.

Actually it should be an instance variable, but an instance variable
of the class object.

What you’re trying to do is to maintain state on a per-object basis,
and for that you need an instance variable. In fact, you can give
your class objects their own accessor methods, by creating those
methods in the singleton class of the first one:

class C
class << self
attr_accessor :n
end
end

class D < C
end

C.n = 1
p C.n # 1
D.n = 2
p D.n # 2
p C.n # 1

Note that if you do this, you have to use the accessor methods to get
at the values from outside (as is the case with all objects):

class C
def my_class_n
self.class.n
end
end

c = C.new
C.n = 100
puts c.my_class_n # 100

But that’s actually good. Since the object © is maintaining its own
state, it makes perfect sense to have to query it. Class variables
demolish that logic, which is one of a number of reasons I dislike
them.

David

[email protected] wrote:

What I’ll like, is that Child1 and Child2 have their own values of
@@test, but @@test should be initialized and used in Parent.
Also, @@test cannot be an instance variable because it is heavy to
initialize and will be common to all instances of Child1 or Child2.

Class variables and class instance variables sound way too much like
global state coming into the system through a backdoor, I’d avoid both.

Personally, I’d replace lookup through a class variable or class
instance variable with injecting the shared object into instances. The
less shared state, the more flexibility you gain in being able to rewire
your objects.

Disclaimer: I am biased in favour of IoC and DI based “objects floating
in vacuum” designs, especially for scenarios that involve reusing an
expensive-to-create component like this one. If nothing else,
declarative dependency resolution lets you plug in testing components
easier / clearer than imperative (even if Ruby makes the latter easier
in that you’re allowed to molest any object in arbitrary ways.)

David V.

Hi –

On Sun, 29 Oct 2006, David V. wrote:

Personally, I’d replace lookup through a class variable or class
instance variable with injecting the shared object into instances. The
less shared state, the more flexibility you gain in being able to rewire
your objects.

Instance variables don’t involve shared state, though; they’re
strictly per object (Class object or otherwise).

David