Class variables per subclasses, defined in the superclass

G

Gareth Adams

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?
 
S

Stefano Crocco

Alle marted=EC 11 dicembre 2007, Gareth Adams ha scritto:
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
=3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f= orename=3D>1}
-- Processor::CampaignMonitor.related_questions
=3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f= orename=3D>1}
-- Processor::Base.related_questions
=3D> {:surname=3D>1, :email=3D>1, :location=3D>1, :phone_number=3D>1, :f= orename=3D>1}

where the expected output is

-- Processor::Sponge.related_questions
=3D> {:location=3D>1, :phone_number=3D>1}
-- Processor::CampaignMonitor.related_questions
=3D> {:surname=3D>1, :email=3D>1, :forename=3D>1}
-- Processor::Base.related_questions
=3D> {} # 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?

I think you need class instance variable, not class variables. Class instan=
ce=20
variable are instance variables of the class object itself. For example:

class A
@var =3D 1
end

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

class A

@var =3D 1
=20
def self.var
@var
end=20

def a_method
puts self.class.va
end

end

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

To use class instance variables, you should replace @@related_questions wit=
h=20
@related_questions and remove the call to class_eval (they aren't needed=20
anymore).

I hope this helps

Stefano
 
P

Phrogz

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'"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top