From: dblack@... Date: 2006-10-02T06:29:17+09:00 Subject: Re: Fixed: dynamic include ---2049402039-1006382877-1159738154=:22266 Content-Type: MULTIPART/MIXED; BOUNDARY="-2049402039-1006382877-1159738154=:22266" This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. ---2049402039-1006382877-1159738154=:22266 Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed Content-Transfer-Encoding: QUOTED-PRINTABLE Hi -- On Mon, 2 Oct 2006, Florian A=DFmann wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > > Am 01.10.2006 um 21:14 schrieb David Vallner: > >> Florian A=DFmann wrote: >>> To be complete here if the Exception: >>>=20 >>> NameError: undefined local variable or method `role' for >>> #> >>>=20 >>=20 >> I smell a Ruby bug / gotcha. >>=20 >> Apparently, in metaclass scope, the surrounding scope just isn't visible= =2E >>=20 >> Try a workaround: >>=20 >> person.roles.each do |role| >> if role.class.const_defined?('Functions') >> class << person >> =09 self >> end.class_eval do >> include role.class.const_get('Functions') >> end >> end >> end unless person.nil? >>=20 >> David Vallner >>=20 >> PS: Statement modifiers after whole blocks? Ick. >>=20 > > Ok, I just tested it, but now even a person with a CustomerRole and no=20 > 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 :) The two techniques should give you the same results. If you have a case where they don't, I'd be interested in seeing it. > Result... > > if person =3D self.send( dyn_finder, *find_args ) > m_name =3D 'Functions' > functions =3D 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 That call to inject will always return an array, so the "and" will always flip to the right and execute person.extend *functions -- even if functions is empty, in which case you'll get an error. You'd probably want to drop the "and" and just do a conditional test: person.extend *functions unless functions.empty? David --=20 David A. Black | dblack@wobblini.net Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3] DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4] [1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com [2] http://dablog.rubypal.com | [4] http://www.rubycentral.org ---2049402039-1006382877-1159738154=:22266-- ---2049402039-1006382877-1159738154=:22266--