From: David Masover Date: 2008-08-29T13:45:32+09:00 Subject: Re: Difficult Inheritance Problem On Wednesday 27 August 2008 06:44:46 James Coglan wrote: > > > > The easiest way I can think of is: > > > > class Page > > class << self > > attr_accessor :difference_mapping > > end > > def self.inherited(c) > > c.difference_mapping = difference_mapping > > end > > end > > > > Page.difference_mapping = { :blah => :blah } > > > > class Next < Page > > end > > > > p Next.difference_mapping # { :blah => :blah } > > > > Depends whether you only need the definition done once. This technique will > not cause the subclass to reflect the parent class' value if it is changed, In that case, let me take a shot: class Page class << self attr_accessor :difference_mapping end module DescendantClassMethods def difference_mapping Page.difference_mapping end def difference_mapping= value Page.difference_mapping = value end end def self.inherited klass klass.extend DescendantClassMethods end end Since I'm in a late-night hacking mood, here's a way that's even more meta: # because << drives me crazy require 'metaid' # name it whatever you want... module ClassVariables module BaseClassMethods def class_variable name self.meta_eval do attr_accessor name end superclass = self (self::InheritableClassVariables ||= Module.new).module_eval do define_method name do superclass.send name end assignment = :"#{name}=" define_method assignment do |value| superclass.send assignment, value end end end def inherited klass mod = self::InheritableClassVariables # I think this, instead of extend, will let subclasses override # these methods properly. klass.meta_eval do include mod end end end def self.included mod mod.extend BaseClassMethods end end Hmm. That's... mostly complete. Usage would be: class Page include ClassVariable class_variable :difference_mapping end But I haven't so much as executed it to check for syntax errors.