From: Robert Klemme Date: 2005-01-26T03:45:50+09:00 Subject: Re: Self and Ruby Comparisons "Robert Klemme" schrieb im Newsbeitrag news:35nhdhF4pbf8dU1@individual.net... > > "Trans" schrieb im Newsbeitrag > news:1106671007.050300.117620@z14g2000cwz.googlegroups.com... > > robert, > > > > Class swapping was brought up on suby-ruby awhile ago under the topic > > of "Soul of a New Machine" (among others). The basic idea was an > > anology along the following lines: > > > > Lets say you have a Person, that preson does all the usual person > > things. But today that person has a job as a Fireman, so he goes to > > work and changes modes. Perhaps at night he goes home and must change > > modes again and be a Boyfriend (hopefully that means some fun methods > > are involved ;-) > > > > Okay so the notion is that an object can take on another level of > > abstraction, such that it's instance vars are essentially its "soul" > > and they can be embuded into different classes. > > > > It's sort of an inverted way to look the use of #become. But I think, a > > much more undersandable and applicable way to look at. > > I missed the term "role" in your explanation. Cause that's the way I had > described this: the person changes her roles over time. Changing the > class is certainly an option here although in this example you would > likely want to restrict classes to sub classes of Person. > > But what do you do if the Person needs to play several roles at a time? > Change the class for each method invocation? That's likely going to be > inefficient - and considering multiple threads it restricts concurrency > dramatically. > > In Ruby the ideal way IMHO would be to have the reverse method of #extend > so if an instance takes on a role it uses a special mixin module's methods > and un-mixes this module when it leaves the role. Of course other > approaches are feasible, too. (Delegator instances that extend the role > module for example.) Illustration: require 'delegate' class Object def role(mod) (@roles ||= {})[mod] ||= SimpleDelegator.new(self).extend(mod) end def role?(mod) @roles and @roles.has_key? mod end def unrole(mod) @roles and @roles.delete(mod) end def roles @roles ? @roles.keys : [] end end class Foo attr_accessor :name end module Bar def xx() name() end end f = Foo.new f.name = "George" puts f.role? Bar p f.role(Bar).xx() puts f.role? Bar p f.roles f.unrole(Bar) p f.roles puts f.role? Bar Regards robert