# Creating classes on the fly

**URL:** <https://rubytalk.org/t/creating-classes-on-the-fly/13057>\
**Category:** ruby-talk\
**Created:** [14 August 2004 19:31 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057 "2004-08-14T19:31:11Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Claus\_Spitzer](https://avatars.discourse-cdn.com/v4/letter/c/49beb7/32.png) [@Claus\_Spitzer](https://rubytalk.org/u/Claus_Spitzer)\
**Post date:** [14 August 2004 19:31 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/1 "2004-08-14T19:31:11Z")

</div>

Greetings again! I'm trying to create a user-defined class on the fly.  
The idea would be for the user to provide a class name, maybe a  
superclass name, and some method definition as a string, e.g.

&nbsp;&nbsp;str1 = "MyClass"  
&nbsp;&nbsp;str2 = "Class"  
&nbsp;&nbsp;str3 = "def bar \n p \"bar!\" \n end"

and then my program would perhaps do something like

&nbsp;&nbsp;eval "class #{str1} \< #{str2}\n #{str3} \n end"

So far so good. Security is not a concern, this is just for a proof of  
concept. But I would like to be able to then extend MyClass  
separately, e.g.

&nbsp;&nbsp;module Mod  
&nbsp;&nbsp;&nbsp;&nbsp;def bar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p "foo!"  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;end

&nbsp;&nbsp;class ???  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Mod  
&nbsp;&nbsp;end

I'm stuck on the ??? part. I tried

&nbsp;&nbsp;class eval( str1 )

I tried

&nbsp;&nbsp;class str.intern # (I think I know by now why this one was a stupid idea)

I tried

&nbsp;&nbsp;$myclassref = eval str1  
&nbsp;&nbsp;class $myclassref

All to no avail. So I'm wondering whether I'm trying to do this the  
wrong way. What would be the Ruby way of solving this problem?

---

<div class="post-metadata">

**Author:** ![Sam\_Stephenson](https://avatars.discourse-cdn.com/v4/letter/s/90db22/32.png) [@Sam\_Stephenson](https://rubytalk.org/u/Sam_Stephenson)\
**Post date:** [14 August 2004 19:40 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/2 "2004-08-14T19:40:41Z")

</div>

Sam

> **···**
>
> On Sun, 15 Aug 2004 04:31:11 +0900, Claus Spitzer \<docboobenstein@gmail.com\> wrote:
> 
> > I'm stuck on the ??? part. I tried
> > 
> > &nbsp;&nbsp;class eval( str1 )
> > 
> > I tried
> > 
> > &nbsp;&nbsp;class str.intern # (I think I know by now why this one was a stupid idea)
> > 
> > I tried
> > 
> > &nbsp;&nbsp;$myclassref = eval str1  
> > &nbsp;&nbsp;class $myclassref
> > 
> > All to no avail. So I'm wondering whether I'm trying to do this the  
> > wrong way. What would be the Ruby way of solving this problem?
> > 
> > klass = eval(str1)  
> > klass.class\_eval do  
> > &nbsp;&nbsp;include Mod  
> > end

---

<div class="post-metadata">

**Author:** ![Claus\_Spitzer](https://avatars.discourse-cdn.com/v4/letter/c/49beb7/32.png) [@Claus\_Spitzer](https://rubytalk.org/u/Claus_Spitzer)\
**Post date:** [14 August 2004 19:41 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/3 "2004-08-14T19:41:36Z")

</div>

To give you a better idea of what I was looking for, I'm trying to do  
the Ruby equivalent of this Smalltalk code

&nbsp;&nbsp;\>myClassname myCat myClass|  
&nbsp;&nbsp;myCat := 'Foo Classes'.  
&nbsp;&nbsp;myClassname := 'MyClass'.  
&nbsp;&nbsp;(Smalltalk hasClassNamed: myClassname) ifTrue: [Smalltalk  
removeClassNamed: myClassname].  
&nbsp;&nbsp;(Smalltalk organization) addCategory:myCat before: 'Kernel-Methods'.  
&nbsp;&nbsp;(ClassBuilder new) superclass:Object subclass: (myClassname  
asSymbol) instanceVariableNames:''  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;classVariableNames: '' poolDictionaries: '' category: myCat.

&nbsp;&nbsp;myClass := Smalltalk classNamed: myClassname.

&nbsp;&nbsp;myClass addInstVarName: 'x';addClassVarName: 'X'.

&nbsp;&nbsp;(myClass respondsTo: ('getx' asSymbol)) ifFalse:[  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myClass compile: 'getx  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ x' classified: 'accessors'].  
&nbsp;&nbsp;(myClass canUnderstand: ('getX' asSymbol)) ifFalse:[  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;myClass compile: 'getX  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;^ X' classified: 'accessors'].  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  
&nbsp;&nbsp;Transcript clear;show: (myClass definition).  
&nbsp;&nbsp;Transcript cr;show: (myClass selectors).  
&nbsp;&nbsp;(myClass new) perform: ('getx' asSymbol); perform: ('getX' asSymbol).

Cheers!  
&nbsp;&nbsp;-CWS

> **···**
>
> On Sat, 14 Aug 2004 15:30:57 -0400, Claus Spitzer \<docboobenstein@gmail.com\> wrote:
> 
> > Greetings again! I'm trying to create a user-defined class on the fly.  
> > The idea would be for the user to provide a class name, maybe a  
> > superclass name, and some method definition as a string, e.g.
> > 
> > &nbsp;&nbsp;str1 = "MyClass"  
> > &nbsp;&nbsp;str2 = "Class"  
> > &nbsp;&nbsp;str3 = "def bar \n p \"bar!\" \n end"
> > 
> > and then my program would perhaps do something like
> > 
> > &nbsp;&nbsp;eval "class #{str1} \< #{str2}\n #{str3} \n end"
> > 
> > So far so good. Security is not a concern, this is just for a proof of  
> > concept. But I would like to be able to then extend MyClass  
> > separately, e.g.
> > 
> > &nbsp;&nbsp;module Mod  
> > &nbsp;&nbsp;&nbsp;&nbsp;def bar  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p "foo!"  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;end
> > 
> > &nbsp;&nbsp;class ???  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Mod  
> > &nbsp;&nbsp;end
> > 
> > I'm stuck on the ??? part. I tried
> > 
> > &nbsp;&nbsp;class eval( str1 )
> > 
> > I tried
> > 
> > &nbsp;&nbsp;class str.intern # (I think I know by now why this one was a stupid idea)
> > 
> > I tried
> > 
> > &nbsp;&nbsp;$myclassref = eval str1  
> > &nbsp;&nbsp;class $myclassref
> > 
> > All to no avail. So I'm wondering whether I'm trying to do this the  
> > wrong way. What would be the Ruby way of solving this problem?

---

<div class="post-metadata">

**Author:** ![Mauricio\_Fernndez](https://avatars.discourse-cdn.com/v4/letter/m/e495f1/32.png) [@Mauricio\_Fernndez](https://rubytalk.org/u/Mauricio_Fernndez)\
**Post date:** [14 August 2004 19:42 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/4 "2004-08-14T19:42:53Z")

</div>

> Greetings again! I'm trying to create a user-defined class on the fly.  
> The idea would be for the user to provide a class name, maybe a  
> superclass name, and some method definition as a string, e.g.

[...]

> So far so good. Security is not a concern, this is just for a proof of  
> concept. But I would like to be able to then extend MyClass  
> separately, e.g.
> 
> &nbsp;&nbsp;module Mod  
> &nbsp;&nbsp;&nbsp;&nbsp;def bar  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p "foo!"  
> &nbsp;&nbsp;&nbsp;&nbsp;end  
> &nbsp;&nbsp;end
> 
> &nbsp;&nbsp;class ???  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;include Mod  
> &nbsp;&nbsp;end
> 
> I'm stuck on the ??? part. I tried

> > def make\_class(name, p, code); r = Class.new(p.split(/::/).inject(Object){|s,x|s.const\_get(x)}); Object.const\_set(name, r); r.module\_eval code; r end

=\> nil

> > class A; class B; end end

=\> nil

> > klass = make\_class "Foo", "A::B", "def bar; 'bar' end"

=\> Foo

> > klass.ancestors

=\> [Foo, A::B, Object, Kernel]

> > klass.new.bar

=\> "bar"

You can later modify klass dynamically with module\_eval, define\_method,  
etc.

> **···**
>
> On Sun, Aug 15, 2004 at 04:31:11AM +0900, Claus Spitzer wrote:
> 
> --  
> Running Debian GNU/Linux Sid (unstable)  
> batsman dot geo at yahoo dot com

---

<div class="post-metadata">

**Author:** ![Claus\_Spitzer](https://avatars.discourse-cdn.com/v4/letter/c/49beb7/32.png) [@Claus\_Spitzer](https://rubytalk.org/u/Claus_Spitzer)\
**Post date:** [14 August 2004 20:03 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/5 "2004-08-14T20:03:08Z")

</div>

Great! Thanks for the quick response. Just another quick one on that context:

Now that I have the class definition and can extend it easily, I'm  
wondering how I would do

qux = Klass.new

using str1 or klass. I could do

eval "qux = #{str}.new"

and that would be fine, but it somehow seems forced. Any hints?

> **···**
>
> On Sun, 15 Aug 2004 04:40:41 +0900, Sam Stephenson \<sstephenson@gmail.com\> wrote:
> 
> > On Sun, 15 Aug 2004 04:31:11 +0900, Claus Spitzer \> \<docboobenstein@gmail.com\> wrote:  
> > \> I'm stuck on the ??? part. I tried  
> > \>  
> > \> class eval( str1 )  
> > \>  
> > \> I tried  
> > \>  
> > \> class str.intern # (I think I know by now why this one was a stupid idea)  
> > \>  
> > \> I tried  
> > \>  
> > \> $myclassref = eval str1  
> > \> class $myclassref  
> > \>  
> > \> All to no avail. So I'm wondering whether I'm trying to do this the  
> > \> wrong way. What would be the Ruby way of solving this problem?  
> > \>
> > 
> > \> klass = eval(str1)  
> > \> klass.class\_eval do  
> > \> include Mod  
> > \> end
> > 
> > Sam

---

<div class="post-metadata">

**Author:** ![Jamis\_Buck4](https://avatars.discourse-cdn.com/v4/letter/j/54ee81/32.png) [@Jamis\_Buck4](https://rubytalk.org/u/Jamis_Buck4)\
**Post date:** [14 August 2004 20:14 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/6 "2004-08-14T20:14:59Z")

</div>

Claus Spitzer wrote:

> Great! Thanks for the quick response. Just another quick one on that context:
> 
> Now that I have the class definition and can extend it easily, I'm  
> wondering how I would do
> 
> qux = Klass.new
> 
> using str1 or klass. I could do
> 
> eval "qux = #{str}.new"
> 
> and that would be fine, but it somehow seems forced. Any hints?

Hmm. If I understand the question, the following should work:

&nbsp;&nbsp;&nbsp;klass = eval( str )  
&nbsp;&nbsp;&nbsp;qux = klass.new

- Jamis

> **···**
>
> --  
> Jamis Buck  
> jgb3@email.byu.edu  
> [http://www.jamisbuck.org/jamis](http://www.jamisbuck.org/jamis)
> 
> "I use octal until I get to 8, and then I switch to decimal."

---

<div class="post-metadata">

**Author:** ![Claus\_Spitzer](https://avatars.discourse-cdn.com/v4/letter/c/49beb7/32.png) [@Claus\_Spitzer](https://rubytalk.org/u/Claus_Spitzer)\
**Post date:** [14 August 2004 20:58 UTC](https://rubytalk.org/t/creating-classes-on-the-fly/13057/7 "2004-08-14T20:58:35Z")

</div>

Err... actually I just figured that out myself a minute ago :-p . I'm  
not at my brightest today. Thanks for the reply though!

> **···**
>
> > Hmm. If I understand the question, the following should work:
> > 
> > &nbsp;&nbsp;&nbsp;klass = eval( str )  
> > &nbsp;&nbsp;&nbsp;qux = klass.new
> > 
> > - Jamis
> > 
> > --  
> > Jamis Buck  
> > jgb3@email.byu.edu  
> > [http://www.jamisbuck.org/jamis](http://www.jamisbuck.org/jamis)
> > 
> > "I use octal until I get to 8, and then I switch to decimal."
