[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

dynamic include

Florian Aßmann

10/1/2006 6:18:00 PM

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

9 Answers

David Vallner

10/1/2006 6:53:00 PM

0

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 Vallner

Florian Aßmann

10/1/2006 7:02:00 PM

0

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


Am 01.10.2006 um 20:53 schrieb David Vallner:

> 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 Vallner
>

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-----

Florian Aßmann

10/1/2006 7:04:00 PM

0

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

Am 01.10.2006 um 20:53 schrieb David Vallner:

> 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 Vallner
>

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-----

David Vallner

10/1/2006 7:15:00 PM

0

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 Vallner

PS: Statement modifiers after whole blocks? Ick.

dblack

10/1/2006 7:38:00 PM

0

David Vallner

10/1/2006 8:06:00 PM

0

On Mon, 2006-10-02 at 04:37 +0900, dblack@wobblini.net wrote:
> You could also use extend, and avoid having to do the thing that won't
> be easy until RCR 231 is accepted :-)

Could've sworn extend was private or protected... On second thought,
that would make the method pretty much useless.

*facewall*

There goes the attempt at remembering the little I can about the messier
meta stuff.

David Vallner

Florian Aßmann

10/1/2006 8:29:00 PM

0

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


Am 01.10.2006 um 21:14 schrieb David Vallner:

> 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 Vallner
>
> 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. :D
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-----

dblack

10/1/2006 9:29:00 PM

0

Florian Aßmann

10/1/2006 9:45:00 PM

0

After a Test/Unit failed because of an Exception I did: <code>p
functions</code> in my source.
It shows me that at one time <var>functions</var> was False, so I
added the && operator.

Regards
Florian