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
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
···
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'
···
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
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.
Hi --
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.
The class keyword always creates a new scope, whether you give it a
constant argument or a "<< obj"-style argument.
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?
You could also use extend, and avoid having to do the thing that won't
be easy until RCR 231 is accepted 
person.roles.each do |role|
if role.class.const_defined?('Functions')
person.extend role.class.const_get('Functions')
end
end
David
···
On Mon, 2 Oct 2006, David Vallner wrote:
--
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] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
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
···
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.
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
···
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 
Hi --
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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. 
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 = 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
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
···
On Mon, 2 Oct 2006, Florian Aßmann wrote:
Am 01.10.2006 um 21:14 schrieb David Vallner:
--
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] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org
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