# Automagic class prototyping

**URL:** <https://www.ruby-forum.com/t/automagic-class-prototyping/99855>\
**Category:** Ruby\
**Created:** [July 25, 2006, 11:28pm UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855 "2006-07-25T23:28:55Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 25, 2006, 11:28pm UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/1 "2006-07-25T23:28:55Z")

</div>

Anybody know any slick techniques for automatically prototyping  
classes so they can interact with each other in top-level code? I’ve  
run through two methods, but I’m not real wild about either of them.

Say for example, classes represent some security label and I want to  
allow things with one label to access those of another label. So,  
these hypothetical classes all descent from Sec…

class Sec  
class \<\<self  
def allow©  
(@allowed\_classes||=[]) \<\<c  
end  
end  
end

And I want to ultimately just indescriminately run stuff like this:

class Documents \< Sec  
allow Downloads  
end

class Downloads \< Sec  
allow Documents  
end

But this is a run-time error unless the classes are prototyped somehow.  
Like:

class Downloads \< Sec; end

class Documents \< Sec  
allow Downloads  
end

class Downloads \< Sec  
allow Documents  
end

As a framework, this would be so much nicer for the end-user if it  
does that automatically, so she doesnt have to thing about declaration  
order. So thats the problem. Possible solutions I’ve tried:

1. Grep-prototyping:  
File.grep out all class defs and eval them before I actually require  
the code. I don’t like this because it chokes on classes defined  
inside of modules or other classes. Grep has no idea about the  
structure of the ruby code.

2. Delayed execution of the ‘allow’ statements.  
I dump allow statements off into proc’s then after all the definitions  
are loaded, I run them. This works great, but syntactically its  
clunky.

class Documents \< Sec  
later do  
allow Downloads  
end  
end

class Downloads \< Sec  
later do  
allow Documents  
end  
end

with:  
class Sec  
class \<\< self  
def later(&code)  
(@code\_for\_later||=[]) \<\< code  
end  
end

And I go back and exec all the @code\_for\_later blocks when all the  
files are require’d. So, if any of you have questions about this code  
or have any ideas for a prettier way to do it, I’d love to hear it.

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 1:52am UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/2 "2006-07-26T01:52:25Z")

</div>

Aleks Kissinger wrote:

> def allow©  
> end  
> class Documents \< Sec
> 
> 1. Grep-prototyping:  
> File.grep out all class defs and eval them before I actually require  
> the code. I don’t like this because it chokes on classes defined  
> inside of modules or other classes. Grep has no idea about the  
> structure of the ruby code.
> 
> 2. Delayed execution of the ‘allow’ statements.  
> I dump allow statements off into proc’s then after all the definitions  
> are loaded, I run them. This works great, but syntactically its  
> clunky.

3:  
class Sec  
class \<\<self  
def allow©  
begin  
Kernel.const\_get©  
rescue NameError #is there a better way to do this?  
class c \< Sec; end  
end  
(@allowed\_classes||=[]) \<\<c  
end  
end  
end

There’s probably stuff in there to trip you up, but you get the idea.  
I’m not too keen on using an exception like that, but I can’t seem to  
find a better or more succinct way to test for the existence of a class.

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 3:17am UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/3 "2006-07-26T03:17:58Z")

</div>

If you merge the functions of your #later and #allow, you could write  
something like this:

class Documents \< Sec  
allow{Downloads}  
end

class Downloads \<Sec  
allow{Documents}  
end

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 7:42am UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/4 "2006-07-26T07:42:51Z")

</div>

Thanks for the suggestions. The problem with the rescue on NameError  
technique is the exception gets thrown before we’re actually in the  
method body of allow, since the offender is a parameter. I dig the  
idea of combining allow and later, but it gets a little uglier since I  
really need allow to take multiple args…

allow {[ClassA, ClassB, OpC]}

However, thats nicer looking than some of the other alternatives. If  
there was some sort of hook or metaprogramming magic that would delay  
executing class bodies until everything was defined, that would be  
ideal, but that might be stretching a little too far.

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 3:31pm UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/5 "2006-07-26T15:31:02Z")

</div>

I can see some pitfalls here, but this is the most promising technique  
I’ve seen so far.

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 8:33am UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/6 "2006-07-26T08:33:40Z")

</div>

On Wed, 26 Jul 2006, Aleks Kissinger wrote:

> def allow©  
> end  
> class Documents \< Sec  
> allow Downloads  
> end
> 
> class Downloads \< Sec  
> allow Documents  
> end
> 
> As a framework, this would be so much nicer for the end-user if it  
> does that automatically, so she doesnt have to thing about declaration  
> order. So thats the problem. Possible solutions I’ve tried:

harp:~ \> cat a.rb  
class Sec  
ALLOWED\_CLASSES = []

def self.allowed\_classes  
ALLOWED\_CLASSES  
end

def self.allow \*list  
allowed\_classes.push \*list  
allowed\_classes.uniq!  
allowed\_classes  
end

def self.const\_missing c  
c  
end

def self.allowed  
allowed\_classes.map{|c| eval c.to\_s }  
end  
end

class Documents \< Sec  
allow Downloads  
end

class Foobar \< Sec  
allow Downloads  
end

class Downloads \< Sec  
allow Documents, Foobar  
end

p Sec.allowed

harp:~ \> ruby a.rb  
[Downloads, Documents, Foobar]

i’d push/pop that ‘const\_missing’ handler during the ‘allow’ method to  
avoid  
any nasty recursion. but there ya go.

-a

---

<div class="post-metadata">

**Author:** ![Aleks\_Kissinger](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/a/a587f6/32.png) [@Aleks\_Kissinger](https://www.ruby-forum.com/u/Aleks_Kissinger)\
**Post date:** [July 26, 2006, 11:54pm UTC](https://www.ruby-forum.com/t/automagic-class-prototyping/99855/7 "2006-07-26T23:54:13Z")

</div>

On Jul 26, 2006, at 1:40 AM, Aleks Kissinger wrote:

> executing class bodies until everything was defined, that would be  
> ideal, but that might be stretching a little too far.

how about:

class Sec  
def self.const\_missing(constant\_name)  
Object.const\_set(constant\_name, Class.new(Sec))  
end  
end
