From: "Ara.T.Howard" Date: 2005-10-02T04:22:05+09:00 Subject: Re: Creating a Class factory On Sun, 2 Oct 2005, Gavin Kistner wrote: > As noted in another thread, I'm looking at ways of creating a Struct-like > class; one that is a factory for creating classes. I did it one way by using > Struct itself, but I'm not wild about it. I'd like to write my own, that sets > true instance variables instead of struct's members thing. Is Struct using C > magic during its initialize to cause "Struct.new" to return class objects, or > is it just doing the equivalent of the following: > > class Foo > def self.new > klass = Class.new( self ) > # setup klass here > klass > end > end > > Is there a better way to make a class that creates 'instances' which are also > classes? > > Erps, except that the above doesn't work, because if you ask the new class to > inherit from the factory, then 'new' is overridden and doesn't call > initialize. For example: > > class KeywordClass > def self.new( property_hash ) > klass = Class.new( self ) > code = <<-ENDCODE > attr_accessor #{property_hash.keys.map{|k| > k.to_s.intern.inspect}.join(', ')} > def initialize( values={} ) > #{property_hash.map{ |prop,default| > "@#{prop} = values[#{prop.inspect}] || # > {default.inspect}" > }.join("\n")} > end > ENDCODE > klass.class_eval code > klass > end > def foo > "whoa" > end > end > > People = KeywordClass.new :cat=>true > puts People.new.cat > #=> ArgumentError: wrong number of arguments (0 for 1) traits let's you do this easily: harp:~ > cat a.rb require 'traits' class People trait 'cat' => true end p People::new.cat # or module KeywordClass def self::new *a, &b klass = Class::new { a.each{|t| trait t} } klass.module_eval &b if b klass end end People2 = KeywordClass::new 'hat', 'cat' => true p People2::new.cat p People2::new.hat People3 = KeywordClass::new(%w(cat in the hat)){ trait 'striped' => true } person = People3::new People3.reader_traits.each{|t| p t => person.send(t)} harp:~ > ruby a.rb true true nil {"cat"=>nil} {"in"=>nil} {"hat"=>nil} {"the"=>nil} {"striped"=>true} hth. traits also inherit their default values up the general inheritence hierarchy - even for class traits. -a -- =============================================================================== | email :: ara [dot] t [dot] howard [at] noaa [dot] gov | phone :: 303.497.6469 | Your life dwells amoung the causes of death | Like a lamp standing in a strong breeze. --Nagarjuna ===============================================================================