Class variables per subclasses, defined in the superclass

Hi guys,

First the pastie, I got class_eval from #ruby-lang on freenode -
http://pastie.caboo.se/127003

I’ve commented out the Rails specific stuff so I’m sure this is a Ruby
question.

What I’m trying to do is have a per-subclass variable created by a class
method
on the super class (which is called from the subclass). Fun.

When I load in the file above I get

– Processor::Sponge.related_questions
=> {:surname=>1, :email=>1, :location=>1, :phone_number=>1,
:forename=>1}
– Processor::CampaignMonitor.related_questions
=> {:surname=>1, :email=>1, :location=>1, :phone_number=>1,
:forename=>1}
– Processor::Base.related_questions
=> {:surname=>1, :email=>1, :location=>1, :phone_number=>1,
:forename=>1}

where the expected output is

– Processor::Sponge.related_questions
=> {:location=>1, :phone_number=>1}
– Processor::CampaignMonitor.related_questions
=> {:surname=>1, :email=>1, :forename=>1}
– Processor::Base.related_questions
=> {} # possibly nil, it’s not too important as it shouldn’t be called
directly

I’ll be the first to admit I don’t really understand class variables, is
what
I’m trying to do possible without having to add anything to the
subclass?

Alle martedì 11 dicembre 2007, Gareth A. ha scritto:

subclass?
I think you need class instance variable, not class variables. Class
instance
variable are instance variables of the class object itself. For example:

class A
@var = 1
end

They follow the usual rules for instance variables. For example, to
access
them from outside self (and this includes accessing them from instance
methods of the class), you need to provide suitable methods:

class A

@var = 1

def self.var
@var
end

def a_method
puts self.class.va
end

end

Unlike class variables, class instance variables arent shared between
parent
and children classes, so they should work for you (unless Rails, which I
don’t know, requires class variables, of course).

To use class instance variables, you should replace @@related_questions
with
@related_questions and remove the call to class_eval (they aren’t needed
anymore).

I hope this helps

Stefano

On Dec 11, 10:58 am, Gareth A. [email protected] wrote:

What I’m trying to do is have a per-subclass variable created by a class method
on the super class (which is called from the subclass). Fun.

class Base
@thing1 = “Base 1”
class << self
attr_accessor :thing1
attr_reader :thing2
end
def self.thing2=( val )
@thing2 = “I am Thing2, and my value is ‘#{val}’”
end
self.thing2 = ‘Base’
end

p Base.thing1, Base.thing2
#=> “Base 1”
#=> “I am Thing2, and my value is ‘Base’”

Set values for subclasses in the class…

class Bar < Base
@thing1 = “Barthing1”
end

…or later

Bar.thing2 = “Barthing2”

p Bar.thing1, Bar.thing2
#=> “Barthing1”
#=> “I am Thing2, and my value is ‘Barthing2’”

But since class instance variables aren’t shared

the base class (and other subclasses) are unchanged

p Base.thing1, Base.thing2
#=> “Base 1”
#=> “I am Thing2, and my value is ‘Base’”