# Meta-programming

**URL:** <https://www.ruby-forum.com/t/meta-programming/180230>\
**Category:** Ruby\
**Created:** [December 15, 2009, 9:43am UTC](https://www.ruby-forum.com/t/meta-programming/180230 "2009-12-15T09:43:26Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 9:43am UTC](https://www.ruby-forum.com/t/meta-programming/180230/1 "2009-12-15T09:43:26Z")

</div>

I am just starting to expand my Ruby knowledge into the area of  
meta-programming.

I want to be able to create a class dynamically. Lets call it, class  
Person, and then I want to add methods to it dynamically.

From a static point I have managed to compile the following example:

class Person  
def self.extend\_me  
class\_eval “def greet; puts ‘hello’; end”  
instance\_eval “def name; puts ‘Person’; end”  
end  
end

Person.extend\_me

Person.respond\_to? :greet  
Person.respond\_to? :name

puts Person.name  
p = Person.new  
puts p.greet

How would I declared a, ‘class Person’ dynamically and then add methods  
and attributes to it? Can someone point me to good documentation on this  
or show me some simple code example?

–  
Kind Regards,  
Rajinder Y.

[http://DevMentor.org](http://DevMentor.org)

Do Good! - Share Freely

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 11:06am UTC](https://www.ruby-forum.com/t/meta-programming/180230/2 "2009-12-15T11:06:53Z")

</div>

Rajinder Y. wrote:

> How would I declared a, ‘class Person’ dynamically

Option 1: since you’re using string eval already, you could just do the  
same.

eval “class Person; end”

Option 2:

Person = Class.new # superclass is Object  
Person = Class.new(Mammal) # superclass is Mammal

I find this isn’t often done in practice though. A program which doesn’t  
know in advance which classes it has can be a bit too dynamic 🙂 You  
would probably register your classes somewhere to be able to find them.  
In a Hash is one option; under a Module is another, so you can use

MyModule.constants

to find them all.

You can make your classes anonymous if you don’t bind them to a  
constant:

my\_klass = Class.new

> and then add methods and attributes to it?

As you’ve done before, using string eval, is one way.

Another way:

```
Person.class_eval { define_method(:greet) { puts "Hello" } }

```

This means that the method is a closure, and can access variables  
outside (unlike ‘def’ which starts a fresh scope), and this can be  
useful sometimes.

Another way: put the method(s) of interest in module(s), then include  
the relevant ones.

```
Person.class_eval { include Greeter }

```

ActiveRecord is a plentiful source of examples.

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 11:50am UTC](https://www.ruby-forum.com/t/meta-programming/180230/3 "2009-12-15T11:50:28Z")

</div>

On Tue, Dec 15, 2009 at 9:32 AM, Rajinder Y. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> class\_eval “def greet; puts ‘hello’; end”  
> p = Person.new  
> puts p.greet
> 
> How would I declared a, ‘class Person’ dynamically and then add methods and  
> attributes to it? Can someone point me to good documentation on this or show  
> me some simple code example?

If you want to define the class dynamically, take a look at Class.new.  
This creates an anonymous class that you can assign to a constant  
directly or with const\_set.  
To define methods I would use define\_method. Adding attributes is done  
adding methods that set and get the attributes:

irb(main):042:0\> C = Class.new do  
irb(main):043:1\* def self.add\_method(name, &blk)  
irb(main):044:2\> define\_method(name, &blk)  
irb(main):045:2\> end  
irb(main):046:1\> end  
=\> C

irb(main):051:0\> C.add\_method(:name) {@name}  
=\> #Proc:0xb7cb9de8@:51(irb)  
irb(main):052:0\> C.add\_method(:name=) {|value| @name = value}  
=\> #Proc:0xb7cb3bf0@:52(irb)  
irb(main):053:0\> c = C.new  
=\> #\<C:0xb7cb16d4\>  
irb(main):054:0\> c.name=3  
=\> 3  
irb(main):055:0\> c.name  
=\> 3

Hope this helps,

Jesus.

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 12:23pm UTC](https://www.ruby-forum.com/t/meta-programming/180230/4 "2009-12-15T12:23:14Z")

</div>

Brian C. wrote:

> Person = Class.new # superclass is Object
> 
> ActiveRecord is a plentiful source of examples.

Hi Brian,

thanks for the excellent examples and explanation =), I can’t stop  
smiling about how beautiful and elegantly simple Ruby make things.

–  
Kind Regards,  
Rajinder Y.

[http://DevMentor.org](http://DevMentor.org)

Do Good! - Share Freely

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 12:35pm UTC](https://www.ruby-forum.com/t/meta-programming/180230/5 "2009-12-15T12:35:24Z")

</div>

JesÃºs Gabriel y GalÃ¡n wrote:

> irb(main):051:0\> C.add\_method(:name) {@name}  
> =\> #Proc:0xb7cb9de8@:51(irb)  
> irb(main):052:0\> C.add\_method(:name=) {|value| @name = value}  
> =\> #Proc:0xb7cb3bf0@:52(irb)  
> irb(main):053:0\> c = C.new  
> =\> #\<C:0xb7cb16d4\>  
> irb(main):054:0\> c.name=3  
> =\> 3  
> irb(main):055:0\> c.name  
> =\> 3

Of course, since ‘name’ is static here, you could just include a module.

It gets more fun when the names of the accessors themselves are dynamic.  
At this point it really does make more sense to use string eval, rather  
than the alternative (instance\_variable\_get and instance\_variable\_set).

Have a look at define\_method\_attribute= in the following:

> <https://github.com/rails/rails/blob/main/activerecord/lib/active_record/attribute_methods/write.rb>

Also see define\_read\_method in attribute\_methods/read.rb, and  
method\_missing in base.rb (this defines finder methods dynamically)

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 12:56pm UTC](https://www.ruby-forum.com/t/meta-programming/180230/6 "2009-12-15T12:56:35Z")

</div>

Brian C. wrote:

> > =\> 3
> 
> Of course, since ‘name’ is static here, you could just include a module.
> 
> It gets more fun when the names of the accessors themselves are dynamic.  
> At this point it really does make more sense to use string eval, rather  
> than the alternative (instance\_variable\_get and instance\_variable\_set).
> 
> Have a look at define\_method\_attribute= in the following:  
> [rails/activerecord/lib/active\_record/attribute\_methods/write.rb at main · rails/rails · GitHub](http://github.com/rails/rails/blob/master/activerecord/lib/active_record/attribute_methods/write.rb)

Thanks for pointing out the path to ActiveRecord, I haven’t gotten use  
to browsing source code, this is really helpful!

> Also see define\_read\_method in attribute\_methods/read.rb, and  
> method\_missing in base.rb (this defines finder methods dynamically)

cool I will do that =)

–  
Kind Regards,  
Rajinder Y.

[http://DevMentor.org](http://DevMentor.org)

Do Good! - Share Freely

---

<div class="post-metadata">

**Author:** ![Rajinder\_Y](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/91b2a8/32.png) [@Rajinder\_Y](https://www.ruby-forum.com/u/Rajinder_Y)\
**Post date:** [December 15, 2009, 12:16pm UTC](https://www.ruby-forum.com/t/meta-programming/180230/7 "2009-12-15T12:16:48Z")

</div>

Jesús Gabriel y Galán wrote:

> > def self.extend\_me  
> > puts Person.name  
> > directly or with const\_set.  
> > irb(main):051:0\> C.add\_method(:name) {@name}  
> > Hope this helps,
> 
> Jesus.

Hi Jesus, yes it does help and you answered the next question I was  
about to ask about adding variables after reading Brian’s reply.

–  
Kind Regards,  
Rajinder Y.

[http://DevMentor.org](http://DevMentor.org)

Do Good! - Share Freely
