Issue extending a delegated class

Hi,

I have a simple class that I'm extending via delegation:

class A
  def one ; puts "A::one" ; two ; end
  def two ; puts "A::two" ; end
end

class B < SimpleDelegator

  def initialize
    a = A.new

    # do some stuff to a

    __setobj__ a
    super( a )
  end
end

I then instantiate B, and use that, all is well. However, i'm running into
issues whenever I try to override a method in B:
b = B.new
class << b
  def two ; puts "foo" ; end
end

I would have expected b.one to output:

···

A::one
custom

But instead i get:
A::one
A::two

However, calling the overriden method directly produces the expected
result. I'm guessing the extend is really only adding the function to the B
instance and not to A? Is there a way to get to A?

Thanks,
-rak-

Hi --

Hi,

I have a simple class that I'm extending via delegation:

class A
def one ; puts "A::one" ; two ; end
def two ; puts "A::two" ; end
end

class B < SimpleDelegator

def initialize
  a = A.new

  # do some stuff to a

  __setobj__ a
  super( a )
end

I then instantiate B, and use that, all is well. However, i'm running into
issues whenever I try to override a method in B:
b = B.new
class << b

You're not overriding anything in B here; rather, you're adding an
instance method to the singleton class of the instance b.

def two ; puts "foo" ; end
end

I would have expected b.one to output:
A::one
custom

(Do you mean "foo" rather than "custom"?)

But instead i get:
A::one
A::two

However, calling the overriden method directly produces the expected
result. I'm guessing the extend is really only adding the function to the B
instance and not to A? Is there a way to get to A?

Your guess is right :slight_smile: When a handles the delegate call to #one,
part of that call is a call to #two -- which, as far as a is
concerned, is A#two.

You can always override A#two, but I imagine that's not what you have
in mind. I'm not sure exactly what you are trying to do, though.

David

···

On Thu, 27 Jul 2006, rak rok wrote:

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

Hi David,

> I would have expected b.one to output:
> A::one
> custom

(Do you mean "foo" rather than "custom"?)

(Woops, yes i meant "foo")

Your guess is right :slight_smile: When a handles the delegate call to #one,
part of that call is a call to #two -- which, as far as a is
concerned, is A#two.

You can always override A#two, but I imagine that's not what you have
in mind. I'm not sure exactly what you are trying to do, though.

Makes sense.. But then how is it possible to override A#two if all I
have is an instance of B?

Thanks!
-rak-

···

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

Hi --

Hi David,

> I would have expected b.one to output:
> A::one
> custom

(Do you mean "foo" rather than "custom"?)

(Woops, yes i meant "foo")

Your guess is right :slight_smile: When a handles the delegate call to #one,
part of that call is a call to #two -- which, as far as a is
concerned, is A#two.

You can always override A#two, but I imagine that's not what you have
in mind. I'm not sure exactly what you are trying to do, though.

Makes sense.. But then how is it possible to override A#two if all I
have is an instance of B?

You really want b's delegated object to have a new #two -- so:

   class << b.__getobj__
     def two
       puts "custom"
     end
   end

or something along those lines.

David

···

On Thu, 27 Jul 2006, rak rok wrote:

Thanks!
-rak-

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
Ruby for Rails => RUBY FOR RAILS (reviewed on
                                     Slashdot, 7/12/2006!)
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
dblack@wobblini.net => me

You really want b's delegated object to have a new #two -- so:

   class << b.__getobj__
     def two
       puts "custom"
     end
   end

Awesome, I didn't know about __getobj__, thanks a lot.

-rak-

PS. Thanks for a great book!