Creating Classes at runtime

D

David Stokar

Hi everybody,
this is my first post and allready a nifty question ;-)

What I want:
Create a NAMED class at runtime. Adding functions is clear.


E.g. somthing like that: (ClassGenerator is an existing module)
module ClassGenerator
def self.generate_new_class ( Parent_Class_Name, Name )
def self.add_method( source )
end

somewhere else:

ClassGenerator::generate_new_class( Fixnum, MyInt );
ClassGenerator::MyInt.add_method( %{ def special_one
return 2
}%
)

Thanks,
David Stokar
 
L

Logan Capaldo

Hi everybody,
this is my first post and allready a nifty question ;-)

What I want:
Create a NAMED class at runtime. Adding functions is clear.


E.g. somthing like that: (ClassGenerator is an existing module)
module ClassGenerator
def self.generate_new_class ( Parent_Class_Name, Name )
def self.add_method( source )
end

somewhere else:

ClassGenerator::generate_new_class( Fixnum, MyInt );
ClassGenerator::MyInt.add_method( %{ def special_one
return 2
}%
)

Thanks,
David Stokar

Object.const_set("MyInt", Class.new(Fixnum))
 
D

David Stokar

David Stokar wrote:
it works like this (just copy and paste)

module ClassGenerator
class Normal
def self.add_method(name, return_value )
define_method( name ) do
return return_value
end
end

def self.add_index( name, index )
define_method( name ) do
return index
end
define_method( 's_'+index.to_s ) do
return name
end
end

def self.foo
puts("Hello from foo")
end
end

def self.generate_new_class(name)#, parent = Class)
const_set(name, Class.new(Normal))
end
end

ClassGenerator.generate_new_class:)MyNew)

ClassGenerator::MyNew.foo
ClassGenerator::MyNew.add_method( 'bar', "Hello from Bar")
s = ClassGenerator::MyNew.new
puts(s.bar)
ClassGenerator::MyNew.add_index('write',1)
ClassGenerator::MyNew.add_index('read',2)
ClassGenerator::MyNew.add_index('create',3)
puts( 'Write: '+s.write.to_s)
puts( 'Read: '+s.read.to_s)
puts( 'Create: '+s.create.to_s)
puts( '1: '+s.s_1)
puts( '2: '+s.s_2)
puts( '3: '+s.s_3)
 
A

ara.t.howard

David Stokar wrote:
it works like this (just copy and paste)

<snip positive impl>


i thought i'd chime in here and point out that the idea of this is flawed:

if you know the name of the class you want to generate, let's say 'MyClass',
and you also want to refer to it via the bareword constant MyClass then you
can simply do

class MyClass; end

and later

class MyClass
def an_added_method
# ...
end
end

the point being that, unless you are going to __also__ going retrieve you
classes via the string name, as in

c = const_get 'MyClass'

obj = c::new


not

c = create_class 'MyClass'

obj = MyClass.new

then you do not need to dynamically create classes by name since the name is
know apriori

perhaps i misunderstodd the OP, but the question did suggest a flawed design.

regards.

-a
 
A

ara.t.howard

Hmm but that still leaves the OP's question unanswered, how can I create
a named class dynamically.

eval "class #{x}; end"
myref2class = Object.const_get(x)


obviously does the job. ( I agree seems flawed to me too, but OP might have
his reasons )

I had a quick look into class.c and it seems that rb_define_class is the
only way to define the name of the class object, which would mean that eval
is the only way to do the trick.

Any opinnions?

i think we've come full circle, but you can do

c = Object.const_set 'C', Class.new{}

i was just unsure it was actually needed

cheers.

-a
 

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,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top