# Dynamic include

**URL:** <https://www.ruby-forum.com/t/dynamic-include/70671>\
**Category:** Ruby\
**Created:** [October 1, 2006, 8:19pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671 "2006-10-01T20:19:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 8:19pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/1 "2006-10-01T20:19:25Z")

</div>

Hello,

I try to include some modules to a class instance, but I have  
problems with the scope, here’s what I did:

person.roles.each do |role|  
class \<\< person  
include role.class.const\_get(‘Functions’)  
end if role.class.const\_defined?(‘Functions’)  
end unless person.nil?

As you can see role is not defined when I include it, does anybody  
know how I can add some singleton methods to person?

Regards  
Florian

---

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 8:53pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/2 "2006-10-01T20:53:29Z")

</div>

Florian AÃ?mann wrote:

> As you can see role is not defined when I include it, does anybody know  
> how I can add some singleton methods to person?

Maybe the module Functions is the culprit? Are the methods module  
functions (“def self.some\_method”), or mixin functions (“def  
some\_method”) in the module?

David V.

---

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 9:03pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/3 "2006-10-01T21:03:29Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Am 01.10.2006 um 20:53 schrieb David V.:

> David V.

Mixin:

class ManagerRole \< Role  
module Functions  
def hire( person )  
self.company \<\< person  
end  
end  
end

Florian  
-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFFIBCMl1R1ZNDW4WgRAhGFAJ4psGPi7gMGGZMgU/pjrOngh1SAFwCeOpgp  
vtlL3+rk4E6LJ2v8mzloyIA=  
=7miO  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 9:15pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/4 "2006-10-01T21:15:30Z")

</div>

Florian AÃ?mann wrote:

> To be complete here if the Exception:
> 
> NameError: undefined local variable or method `role’ for  
> #\<Class:#Person:0x2869aa0\>

I smell a Ruby bug / gotcha.

Apparently, in metaclass scope, the surrounding scope just isn’t  
visible.

Try a workaround:

person.roles.each do |role|  
if role.class.const\_defined?(‘Functions’)  
class \<\< person  
self  
end.class\_eval do  
include role.class.const\_get(‘Functions’)  
end  
end  
end unless person.nil?

David V.

PS: Statement modifiers after whole blocks? Ick.

---

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 10:29pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/5 "2006-10-01T22:29:36Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Am 01.10.2006 um 21:14 schrieb David V.:

> visible.  
> end  
> end unless person.nil?
> 
> David V.
> 
> PS: Statement modifiers after whole blocks? Ick.

Ok, I just tested it, but now even a person with a CustomerRole and  
no ManagerRole role has the methods once they are included, thanks  
anyway. 😃  
dblack, extend works excactly the way I want it to, thank you too 🙂

Result…

if person = self.send( dyn\_finder, \*find\_args )  
m\_name = ‘Functions’  
functions = person.roles.inject([]) do |f,r|  
r.class.const\_defined?(m\_name) and  
f \<\< r.class.const\_get(m\_name)  
end and person.extend \*functions  
end

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFFICUhl1R1ZNDW4WgRAtJUAJ9mHsq/PLfad6hdR8xxFm+Ep6xDKgCggz4D  
5NuWkFwTIcalG5cAOnxbP4M=  
=1k6o  
-----END PGP SIGNATURE-----

---

<div class="post-metadata">

**Author:** ![Florian\_ASSSmann](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/f/c6cbf5/32.png) [@Florian\_ASSSmann](https://www.ruby-forum.com/u/Florian_ASSSmann)\
**Post date:** [October 1, 2006, 9:05pm UTC](https://www.ruby-forum.com/t/dynamic-include/70671/6 "2006-10-01T21:05:30Z")

</div>

-----BEGIN PGP SIGNED MESSAGE-----  
Hash: SHA1

Am 01.10.2006 um 20:53 schrieb David V.:

> David V.

To be complete here if the Exception:

NameError: undefined local variable or method `role' for #<Class:#<Person:0x2869aa0>> /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/ active_record/base.rb:1129:in`method\_missing’  
/Users/boof/Documents/Workspaces/rails/comany/config/…/app/  
models/person.rb:63:in `auth' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/ active_record/associations/association_proxy.rb:110:in`each’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/  
active\_record/associations/association\_proxy.rb:110:in `send' /usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/ active_record/associations/association_proxy.rb:110:in`method\_missing’  
/usr/local/lib/ruby/gems/1.8/gems/activerecord-1.14.4/lib/  
active\_record/associations/has\_and\_belongs\_to\_many\_association.rb:  
81:in `method_missing' /Users/boof/Documents/Workspaces/rails/comany/config/../app/ models/person.rb:60:in`auth’  
test/unit/person\_test.rb:37:in `test\_4\_change\_password’

-----BEGIN PGP SIGNATURE-----  
Version: GnuPG v1.4.5 (Darwin)

iD8DBQFFIBD5l1R1ZNDW4WgRAgE3AJ4iG+Mmilp8wl85NJ/vIx7dWCc9LgCcDOL2  
mX/zP7k1QDGj7t/KJynFlX8=  
=I3VI  
-----END PGP SIGNATURE-----
