From: "Ara.T.Howard" Date: 2005-11-11T02:22:13+09:00 Subject: Re: Golf, anyone? On Fri, 11 Nov 2005, m4dc4p wrote: > I spent a day figuring out how to solve this problem, and it seems like > there should be a much better solution. I wanted to write a module > that, when included in an object, would create a class variable and > accessor for that object. If another class includes the module, it > should have its own class variable and accessor. The class variable > does *not* live in the module - it is not shared by all objects which > include the module. > > A simplified version of what I came up with is below. Module Foo > defines the class variable and accessor. Class Bar and Baz are related > by inheritance. Instance variables a and b are of class Bar and Baz. > Instance variable w is of class Bil, which is not related to either Bar > or Baz. > > When a value is added to the "prop" class variable of either a or > b, they both show it. However, when a value is added to the "prop" > class variable in w, it does not show up in either a or b. > > I'm convinced there is a better way to do this and what I came up > with is just a hack on a kludge. Any and all help is appreciated! > > > module Foo > def self.included(mod) > super(mod) > class << mod; self; end.class_eval <<-EOS > @prop = [] > def prop > @prop ||= [] > end > EOS > > def mod.inherited(p) > def p.prop > superclass.prop > end > > end > end > end > > class Bar > include Foo > end > > class Baz < Bar > end > > class Bil > include Foo > end > > a = Bar.new > b = Bar.new > x = Baz.new > w = Bil.new > > a.class.prop << "p1" > puts "a, b, and x share property added to a: > #{a.class.prop.inspect}, > #{b.class.prop.inspect}, > #{x.class.prop.inspect}" > > b.class.prop << "p2" > puts "and property added to b: > #{a.class.prop.inspect}, > #{b.class.prop.inspect}, > #{x.class.prop.inspect}" > > w.class.prop << "p3" > puts "but not a property added to w. > a: #{a.class.prop.inspect}, > b: #{b.class.prop.inspect}, > x: #{x.class.prop.inspect}, > w: #{w.class.prop.inspect}" > > #>ruby mod_test.rb > #a, b, and x share property added to a: > # ["p1"], > # ["p1"], > # ["p1"] > #and property added to b: > # ["p1", "p2"], > # ["p1", "p2"], > # ["p1", "p2"] > #but not a property added to w. > # a: ["p1", "p2"], > # b: ["p1", "p2"], > # x: ["p1", "p2"], > # w: ["p3"] > > p.s. The implementation here relies on the append_features method of > module, and the inherited method of objects. When an object first > includes the module, the class variable and property are added to the > object via append_features. I found that this this did NOT extend down > the inheritance chain for those objects, though. I was forced to > override the inherrited method on the initial object so I could place > the 'properties' definition in each subclass. This is my least favorite > part of my solution. harp:~ > cat a.rb require "traits" class Bar; class_trait "prop" => [];end class Baz < Bar; end class Bil; class_trait "prop" => [];end a, b, x, w = [Bar, Bar, Baz, Bil].map{|c| c::new} a.class.prop << "p1" puts "a, b, and x share property added to a: #{a.class.prop.inspect}, #{b.class.prop.inspect}, #{x.class.prop.inspect}" b.class.prop << "p2" puts "and property added to b: #{a.class.prop.inspect}, #{b.class.prop.inspect}, #{x.class.prop.inspect}" w.class.prop << "p3" puts "but not a property added to w. a: #{a.class.prop.inspect}, b: #{b.class.prop.inspect}, x: #{x.class.prop.inspect}, w: #{w.class.prop.inspect}" harp:~ > ruby a.rb a, b, and x share property added to a: ["p1"], ["p1"], ["p1"] and property added to b: ["p1", "p2"], ["p1", "p2"], ["p1", "p2"] but not a property added to w. a: ["p1", "p2"], b: ["p1", "p2"], x: ["p1", "p2"], w: ["p3"] you could do it with a Foo module too, but it's excess typing and you said 'golf' ;-) regards. -a -- =============================================================================== | ara [dot] t [dot] howard [at] gmail [dot] com | all happiness comes from the desire for others to be happy. all misery | comes from the desire for oneself to be happy. | -- bodhicaryavatara ===============================================================================