Creating a Class factory

G

Gavin Kistner

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)
 
A

Ara.T.Howard

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
===============================================================================
 
A

Ara.T.Howard

Ara,

Any plans to gemify traits?

Cheers ...

yes. my trouble, attm, is that i'm extremely busy and often update one or two
of my packages per week. the way i sync them all up to
http://codeforpeople.com/lib/ruby is a simple

scp -r ./lib/ruby/* codeforpeople.com:lib/ruby

this, along with writing READMES, minimal docs, and sample programs is all i
can manage. the gem thing is too hard for me to keep up to date with - at
least until i took a few days to setup rake files and tasks to upload to
rubyforge. the other issues i have are that i hate cvs and especially cvs
frontends, the most typical way is use my code is to be editing in vim with
something like

http://codeforpeople.com/lib/ruby/traits/traits-0.7.0/sample/a.rb

open in lynx - all screen'd (screen being the worlds best 'ide' ;-) together
(i develop pretty much without X because i ssh everywhere all the time so
anything gui is out). it's often, once per day, that i have to pull up
something like

http://codeforpeople.com/lib/ruby/lockfile/lockfile-1.3.0/lib/lockfile.rb

because i can't remember how i implemented something. archaic i know, but i
don't really know anyone personally that manages 35 or so libraries with
around 10 of them active at any one time - and that excludes the 30 or so i
manage for work - in a way that sounds easier to me. the other thing i can't
stand about gems is the versioning - it kills me. in any case i realize, on
the one hand, that someone out there probably knows how to skin this cat in
less time that it took me to write this - i'm all ears too - but for now
packing gems and updating them to a gemserver just slows me down too much. i
do have code generators (dumb ones) and scripts i use to manage my current
stuff so i'm open to scriptable ideas that allow easy viewing of the code
online too.

otth it's apparent that gems is the future (gem guys - make them install into
system space and have sane/rigid version please!) so i promise to at least do
something stop-gap to gem-ify my stuff.

cheers.

-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
===============================================================================
 

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

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top