"Robert Klemme" <bob.news / gmx.net> schrieb im Newsbeitrag
news:35nhdhF4pbf8dU1 / individual.net...
>
> "Trans" <transfire / gmail.com> 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