"Robert Klemme" <bob.news / gmx.net> schrieb im Newsbeitrag
news:2s4gf0F1g0lreU1 / uni-berlin.de...
>
> "Yukihiro Matsumoto" <matz / ruby-lang.org> schrieb im Newsbeitrag
> news:1096592771.410462.16363.nullmailer / x31.priv.netlab.jp...
> > Hi,
> >
> > In message "Re: ruby-dev summary 24298-24353"
> >     on Fri, 1 Oct 2004 09:52:34 +0900, "trans.  (T. Onoma)"
> <transami / runbox.com> writes:
> >
> > |> Hmm, "fanctor".  I like the name.
> > |
> > |Is a new class required? I think, Proc could add this feature and
> remain
> > |backward compatible.
> >
> > I just said I liked the name. ;-)
> > I'm not yet sure if we need a new class.
>
> What about the Adaptor idea I posted on 30.9.  Somehow nobody seems to
> have noticed.  I'll repost the core part below.
>
>     robert

Newsreader screwed up.  Here it is:


But the second example shows a more general pattern: what we need here is
an
Adaptor because we might want to check the type of the object returned via
Class#=== to make sure only proper instances go into the Pool.  In Ruby we
often use singleton methods to do method adptions, but there might be
usages
where we don't want to change an instance.  Here's a sample
implementation:

class Adaptor
  def initialize(obj, mappings)
    @obj = obj
    scl = class<<self; self end

    # delegation of all public methods
    obj.public_methods.each do |m|
      m = m.to_sym

      unless mappings[m]
        scl.class_eval { define_method(m) { |*a| @obj.send(m,*a) } }
      end
    end

    # remapping
    mappings.each do |m,mapped|
      case mapped
        when Symbol
          scl.class_eval { define_method(m) {|*a| @obj.send(mapped,*a) } }
        when Proc
          scl.class_eval { define_method(m,&mapped) }
        else
          raise ArgumentError, "Must be Proc or Symbol"
      end
    end
  end
end

With this we can do

>> sample = %w{aa bb cc}
=> ["aa", "bb", "cc"]
>> fake_class = Adaptor.new(sample, :new => :dup, :=== => :==)
=> ["aa", "bb", "cc"]
>> x = fake_class.new
=> ["aa", "bb", "cc"]
>> "Is an instance of? #{fake_class === x}"
=> "Is an instance of? true"
>> x.id == sample.id
=> false