Calling super in overwritten methods

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

Thanks
Joerg

···

--
Posted via http://www.ruby-forum.com/.

Joerg Diekmann wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

No, not without some tortured coding. You have redefined method2 in your
derived class, consequently this redefinition takes precedence in instances
of the derived class, and this is by design, not by accident.

Remember that the call to "method2" in the parent class, called with "super"
as you show it, is still in the context of an instance of the derived
class, so the call is resolved to refer to the derived class method2, not
the parent one.

If, as you say, you really want the result of the parent's method2, then
don't redefine that method in the derived class. Or use different method
names to create the distinction you want.

···

--
Paul Lutus
http://www.arachnoid.com

Indeed but sometime back, we had similar discussion here and someone
(David I guess) proposed:

class Parent
def knox
   puts 'parent'
end
end

class Child < Parent
def knox
   puts 'child'
end
def test
   self.class.superclass.instance_method( :knox ).bind( self ).call
end
end

Child.new.test

···

On 12/6/06, Joerg Diekmann <joergd@pobox.com> wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

Thanks
Joerg

--
There was only one Road; that it was like a great river: its springs
were at every doorstep, and every path was its tributary.

Joerg Diekmann wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

Local methods would do the trick. We don't have those. But here's a
cool way:

  require 'facets'
  require 'kernel/as'

  class A

    def method1
      as(A).method2
    end

    def method2
      return 100
    end

  end

  class B < A
    def method1
      super
    end

    def method2
      return 200
    end
  end

T.

(http://facets.rubyforge.org)

harp:~ > cat a.rb
     class A
       CLASS = self
       def method1 *a, &b
         CLASS.instance_method(:method2).bind(self).call *a, &b
       end
       def method2
         return 100
       end
     end

     class B < A
       CLASS = self
       def method1
         super
       end
       def method2
         return 200
       end
     end

     p A.new.method1
     p B.new.method1

     harp:~ > ruby a.rb
     100

just because you can, however, doesn't mean you should. why do you want to do this?

-a

···

On Wed, 6 Dec 2006, Joerg Diekmann wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
def method1
   method2
end

def method2
   return 100
end
end

class B < A
def method1
   super
end

def method2
   return 200
end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

You didn't say if you can change class a if so you should probably
start the redesign there before resorting to vodoo.

= class A
= def method1
* method2_A
= end

···

=
= def method2
= return 100
= end
+ alias :method2_A :method2
= end

= class B < A
= def method1
= super
= end

= def method2
= return 200
= end
+ alias :method2_B :method2
= end

or so. This makes your intentions quite clear I'd say.

Hey,
Assuming your trying to make a determination in class B as to which
method to use, you could make method2 a class method.

class A
  def method1
    A.method2
  end

  def self.method2
    return 100
  end
end

class B < A
  def method1
    x = 1
    puts A.method2 if x == 1 # => 100
    puts method2 if x == 2 # => 200
  end

  def method2
    return 200
  end
end

B.new.method1

- Brian

···

On Dec 6, 5:36 am, Joerg Diekmann <joe...@pobox.com> wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

Thanks
Joerg

--
Posted viahttp://www.ruby-forum.com/.

Ok pity there's no simple Ruby solution to it. I'll just have to rename
my methods in my derived class then. Thanks though!

···

No, not without some tortured coding. You have redefined method2 in your
derived class, consequently this redefinition takes precedence in
instances
of the derived class, and this is by design, not by accident.

--
Posted via http://www.ruby-forum.com/\.

Ok, that qualifies as 'ruby-fu' :slight_smile:

···

   self.class.superclass.instance_method( :knox ).bind( self ).call

Hmmm ... that doesn't work for me.

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    self.class.superclass.instance_method( :method1 ).bind( self ).call
  end

  def method2
    return 200
  end
end

b.method1 # Still 200 instead of 100

Hemant Kumar wrote:

···

Indeed but sometime back, we had similar discussion here and someone
(David I guess) proposed:

class Parent
def knox
   puts 'parent'
end
end

class Child < Parent
def knox
   puts 'child'
end
def test
   self.class.superclass.instance_method( :knox ).bind( self ).call
end
end

Child.new.test

--
Posted via http://www.ruby-forum.com/\.

self.class.superclass.instance_method( :knox ).bind( self ).call. It looks tricky and even clunky. Actually this function can be easily realized by C++' compulsory type conversion, as follows:
#include "stdio.h"
class A
{
public: int method1();
           int method2();
};
class B: public A
{
public: int method1();
           int method2();
};
int static main()
{
    B *obj=new B();
    printf("%d\n",((A)*obj).method1());
    return 0;
}
int A::method1() { return method2();}
int A::method2() { return 100;}
int B::method1() { return method2();}
int B::method2() { return 200;}

         However regarding ruby, as in joergd@pobox.com's program, the derived object always invokes the method in its own context, i.e., it invokes method2 of the B object rather than the A object. Anyhow, ruby provides Class Method (different with the method tied to objects) for us, so if you intend to invoke the method of the parent from the derived class which has the same method name, you may define and use Class Method. E.g.,
def A.method2
        return 100;
end

Shiwei
The views expressed are my own and not necessarily those of Oracle and its affiliates.

hemant wrote:

···

On 12/6/06, Joerg Diekmann <joergd@pobox.com> wrote:

Hi - not sure if this is possible - but it feels like it could be with
some serious ruby-fu.

I have the following:

class A
  def method1
    method2
  end

  def method2
    return 100
  end
end

class B < A
  def method1
    super
  end

  def method2
    return 200
  end
end

This is what happens:

b.method1 # 200

But, what I want is:

b.method1 # 100

Is this possible at all?

Thanks
Joerg

Indeed but sometime back, we had similar discussion here and someone
(David I guess) proposed:

class Parent
def knox
  puts 'parent'
end

class Child < Parent
def knox
  puts 'child'
end
def test
  self.class.superclass.instance_method( :knox ).bind( self ).call
end

Child.new.test

Joerg Diekmann wrote:

Ok pity there's no simple Ruby solution to it. I'll just have to rename
my methods in my derived class then. Thanks though!

Having a "simple" way would be way too C++, since it -is- horribly
breaking object-oriented behaviour. Might as well bring back "virtual".

The unbound method Ruby fu is just right in my opinion, it makes it
instantly clear that the code isn't behaving polymorphically, but uses
the class as a function namespace.

David Vallner