Call functions of superclass

I'd like to be able to do
class Parent
        def iamuseful
        end
end
class Child
        def iamuseful
                # do stuff
                super.iamuseful
        end
end
But that gives strange results, I seem to be unable to call methods from a
superclass?

Bart

class Parent
  def useful(parameters)
    #Do stuff
  end
end
class Child < Parent
  def useful(parameters)
    super(parameters)
    # Do more stuff..
  end
end

Farrel

···

On 23/08/06, Bart Braem <bart.braem@gmail.com> wrote:

I'd like to be able to do
class Parent
        def iamuseful
        end
end
class Child
        def iamuseful
                # do stuff
                super.iamuseful
        end
end
But that gives strange results, I seem to be unable to call methods from a
superclass?

Bart

I'd like to be able to do
class Parent
        def iamuseful
        end
end
class Child

class Child < Parent

        def iamuseful
                # do stuff
                super.iamuseful
        end
end
But that gives strange results, I seem to be unable to call methods from a
superclass?

Try the correction above. :wink:

James Edward Gray II

···

On Aug 23, 2006, at 10:30 AM, Bart Braem wrote:

Actually I am curious to know:

class Parent
    def something
    end

    def another
      # do foo
    end
end

class Child < Parent
    def something
      super.another # call _another_ instance method BUT of the superclass, not one's own
    end

    def another
      # do bar instead of foo
    end
end

is that at all possible somehow? Just out of curiosity.

···

On 23-aug-2006, at 17:39, James Edward Gray II wrote:

Try the correction above. :wink:

--
Julian 'Julik' Tarkhanov
please send all personal mail to
me at julik.nl

Farrel Lifson wrote:

class Parent
def useful(parameters)
#Do stuff
end
end
class Child < Parent
def useful(parameters)
super(parameters)
# Do more stuff..
end
end

That's what I was looking for, altough it's a strange use of the super
keyword.
(James Edward Gray II: you were right about the Child < Parent part, I
forgot to include it in my example.)
Another question: I am a bit confused by other responses in this thread. Say
I use the following code:

class Parent
        def somemethod
        end
        def overrideme(param)
        end
end

class Child < Parent
        def overrideme(param)
                # do stuff
                super(param)
                somemethod
        end
end

The somemethod call in Child#overrideme works. Some posts in this thread
seem to say this impossible?

Bart (still learning ruby and starting to love it!)

Julian 'Julik' Tarkhanov wrote:

Try the correction above. :wink:

Actually I am curious to know:

class Parent
    def something
    end

    def another
      # do foo
    end
end

class Child < Parent
    def something

       super # call _another_ instance method BUT of the

superclass, not one's own
    end

    def another
      # do bar instead of foo
    end
end

is that at all possible somehow? Just out of curiosity.

I think that's what you are wanting. It calls the parent's 'another'
method with the exact same parameters as were passed to child's
'another' method. If you want parameters that are different, simply
specify them as if you were calling 'Parent.another(parameter)'. (ie:
super(parameter) )

···

On 23-aug-2006, at 17:39, James Edward Gray II wrote:

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

To satisfy your curiosity,

<code>
#! /usr/bin/ruby -w

class Parent

    def something
      puts "Parent something"
    end

    def another
       puts "Parent another"
    end

end

class Child < Parent

    def something
       puts "Child something"
      super.another
    end

    def another
      puts "Child another"
    end

end

Child.new.something
</code>

<result>
Child something
Parent something
/Users/mg/Desktop/test.rb:19:in `something': undefined method `another' for nil:NilClass (NoMethodError)
  from /Users/mg/Desktop/test.rb:28
</result>

From which I conclude that 'super.another' is parsed as 'super nil.another'

Regards, Morton

···

On Aug 23, 2006, at 11:44 AM, Julian 'Julik' Tarkhanov wrote:

class Parent
   def something
   end

   def another
     # do foo
   end
end

class Child < Parent
   def something
     super.another # call _another_ instance method BUT of the superclass, not one's own
   end

   def another
     # do bar instead of foo
   end
end

Julian 'Julik' Tarkhanov wrote:

Try the correction above. :wink:

Actually I am curious to know:

class Parent
   def something
   end

   def another
       # do foo
   end
end

class Child < Parent
   def something
       super.another # call _another_ instance method BUT of the superclass, not one's own
   end

   def another
       # do bar instead of foo
   end
end

is that at all possible somehow? Just out of curiosity.

Don't have too much exposure to Ruby myself, but spent some time on #ruby-lang asking getting answers to this and the OP's questions a couple of days ago.

AFAIK 'super' simply invokes the overriden method, so your example would be calling the method 'another', on whatever object is returned by Parent::something().

I don't think there's any way to refer to an object as if it had the base classes' type, but you can alias the method before overriding it:

class Child < Parent

   def something
     old_another
   end

   alias :old_another :another
   def another
     # overriding the old one
   end
end

Isak

···

On 23-aug-2006, at 17:39, James Edward Gray II wrote:

--Julian 'Julik' Tarkhanov
please send all personal mail to
me at julik.nl

I think he's wanting to know if it's possible to call a different method
of the superclass than the method that the interpreter is in. For example,

class A
  def zoo
    puts "in zoo"
  end
end

class B < A
  def hoo
    super.zoo
  end
end

b = B.new
b.hoo

will not work -- you must explicitly define method #zoo in class B in
order to call the super version of it in class A. Is there a way to make
the above code work, short of defining zoo in B? I'm curious about this
also.

Nate

···

On Thu, 24 Aug 2006, William Crawford wrote:

Julian 'Julik' Tarkhanov wrote:
> On 23-aug-2006, at 17:39, James Edward Gray II wrote:
>
>> Try the correction above. :wink:
>
> Actually I am curious to know:
>
> class Parent
> def something
> end
>
> def another
> # do foo
> end
> end
>
> class Child < Parent
> def something
       super # call _another_ instance method BUT of the
> superclass, not one's own
> end
>
> def another
> # do bar instead of foo
> end
> end
>
> is that at all possible somehow? Just out of curiosity.

I think that's what you are wanting. It calls the parent's 'another'
method with the exact same parameters as were passed to child's
'another' method. If you want parameters that are different, simply
specify them as if you were calling 'Parent.another(parameter)'. (ie:
super(parameter) )

From which I conclude that 'super.another' is parsed as 'super
nil.another'

No, not really

super call Parent#something which return nil (the result of #puts)
ruby use the result of super (i.e. nil) to call #another
because nil don't respond to #another, it give an error

Guy Decoux

Nathan Smith wrote:

Julian 'Julik' Tarkhanov wrote:
    

Try the correction above. :wink:
        

Actually I am curious to know:

class Parent
    def something
    end

    def another
      # do foo
    end
end

class Child < Parent
    def something
      

       super # call _another_ instance method BUT of the
    

superclass, not one's own
    end

    def another
      # do bar instead of foo
    end
end

is that at all possible somehow? Just out of curiosity.
      

I think that's what you are wanting. It calls the parent's 'another'
method with the exact same parameters as were passed to child's
'another' method. If you want parameters that are different, simply
specify them as if you were calling 'Parent.another(parameter)'. (ie:
super(parameter) )
    
I think he's wanting to know if it's possible to call a different method
of the superclass than the method that the interpreter is in. For example,

class A
  def zoo
    puts "in zoo"
  end
end

class B < A
  def hoo
    super.zoo
  end
end

b = B.new
b.hoo

will not work -- you must explicitly define method #zoo in class B in
order to call the super version of it in class A. Is there a way to make
the above code work, short of defining zoo in B? I'm curious about this
also.

Nate
  

Why would you need to explicitly reference super? It is not necessary:

$ irb
irb(main):001:0> class Parent
irb(main):002:1> def zoo
irb(main):003:2> puts "zoo in Parent!"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0>
irb(main):007:0* class Child < Parent
irb(main):008:1> def hoo
irb(main):009:2> zoo
irb(main):010:2> end
irb(main):011:1> end
=> nil
irb(main):013:0> c = Child.new
=> #<Child:0x39dd78>
irb(main):014:0> c.hoo
zoo in Parent!
=> nil
irb(main):015:0>

If there is some common functionality that needs to be accessed by two methods, one defined in the child class, the other defined in the parent class, I'd say refactor it out into a method in the Parent class and call it from wherever it is needed:

$ irb
irb(main):001:0> class Parent
irb(main):002:1> def common
irb(main):003:2> puts "common in Parent"
irb(main):004:2> end
irb(main):005:1> def foo
irb(main):006:2> puts "foo in Parent"
irb(main):007:2> common
irb(main):008:2> end
irb(main):009:1> end
=> nil
irb(main):010:0> class Child < Parent
irb(main):011:1> def bar
irb(main):012:2> puts "bar in Child"
irb(main):013:2> common
irb(main):014:2> end
irb(main):015:1> end
=> nil
irb(main):016:0> c = Child.new
=> #<Child:0x392c30>
irb(main):017:0> c.bar
bar in Child
common in Parent
=> nil
irb(main):018:0> c.foo
foo in Parent
common in Parent
=> nil

Cheers,
Doug

···

On Thu, 24 Aug 2006, William Crawford wrote:

On 23-aug-2006, at 17:39, James Edward Gray II wrote:

I'm not sure it's a great idea, but sure you can:

def send_super(meth, *args, &blk)
   # hide current method
   if self.class.instance_methods(false).include? meth.to_s
     self.class.send(:alias_method, :_hidden, meth)
     self.class.send(:remove_method, meth)
   end

   send(meth, *args, &blk)
ensure
   self.class.send(:alias_method, meth, :_hidden) if methods.include? "_hidden"
end

class Parent
   def a
     "Hello from Parent!"
   end
end

class Child < Parent
   def a
     "Hello from Child!"
   end

   def b
     send_super(:a)
   end
end

child = Child.new
puts child.b
puts child.a

__END__

James Edward Gray II

···

On Aug 23, 2006, at 11:11 AM, Nathan Smith wrote:

I think he's wanting to know if it's possible to call a different method
of the superclass than the method that the interpreter is in.

You're right. I forgot to take into account that every Ruby method returns an object which cam be the receiver any following message. It's all much clearer when I change the test code to:

<code>
#! /usr/bin/ruby -w

class Parent

    def something
      puts "Parent something"
      self
    end

    def another
       puts "Parent another"
       self
    end

end

class Child < Parent

    def something
       puts "Child something"
      super.another
    end

    def another
      puts "Child another"
    end

end

Child.new.something
</code>

<result>
Child something
Parent something
Child another
</result>

A more correct conclusion would have been that Ruby's 'super' should be regarded more as a method call rather than as a pseudo-variable (such as 'self'). This is quite different than the 'super' of Smalltalk and other object-oriented languages I have past experience with. Do you think Ruby's semantics for 'super' should be regarded as an idiosyncrasy or as an advance over Smalltalk's?

Regards, Morton

···

On Aug 23, 2006, at 12:43 PM, ts wrote:

> From which I conclude that 'super.another' is parsed as 'super
> nil.another'

No, not really

super call Parent#something which return nil (the result of #puts)
ruby use the result of super (i.e. nil) to call #another
because nil don't respond to #another, it give an error

Douglas A. Seifert wrote:

Why would you need to explicitly reference super? It is not necessary:

He has redefined the 'another' method in the child class. But for some
reason, he needs the 'another' method in the parent class instead.

···

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

Why would you need to explicitly reference super? It is not necessary:

$ irb
irb(main):001:0> class Parent
irb(main):002:1> def zoo
irb(main):003:2> puts "zoo in Parent!"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0>
irb(main):007:0* class Child < Parent
irb(main):008:1> def hoo
irb(main):009:2> zoo
irb(main):010:2> end
irb(main):011:1> end

The OP defined method zoo in Child as well, and wanted to call the
Parent's zoo, that's why.

If there is some common functionality that needs to be accessed by two
methods, one defined in the child class, the other defined in the parent
class, I'd say refactor it out into a method in the Parent class and
call it from wherever it is needed:

This seems to be a reasonable approach. I agree that a bit refactoring
is much better than hacking with cross calling methods. OTOH, I am
also curious whether it is possible.

J.

···

On 8/23/06, Douglas A. Seifert <doug@dseifert.net> wrote:

wow, that's way too much work (plus thread-unsafe).

def send_super(meth, *args, &b)
  self.class.superclass.instance_method(meth).bind(self).call(*args, &b)
end

RUBY_VERSION # => "1.8.5"
RUBY_RELEASE_DATE # => "2006-07-07"
class Parent
  def a
    "Hello from Parent!"
  end
end

class Child < Parent
  def a
    "Hello from Child!"
  end

  def b
    send_super(:a)
  end
end

child = Child.new
puts child.b
puts child.a

__END__
# >> Hello from Parent!
# >> Hello from Child!

···

On Thu, Aug 24, 2006 at 01:45:40AM +0900, James Edward Gray II wrote:

On Aug 23, 2006, at 11:11 AM, Nathan Smith wrote:

>I think he's wanting to know if it's possible to call a different method
>of the superclass than the method that the interpreter is in.

I'm not sure it's a great idea, but sure you can:

def send_super(meth, *args, &blk)
  # hide current method
  if self.class.instance_methods(false).include? meth.to_s
    self.class.send(:alias_method, :_hidden, meth)
    self.class.send(:remove_method, meth)
  end

  send(meth, *args, &blk)
ensure
  self.class.send(:alias_method, meth, :_hidden) if methods.include? "_hidden"
end

--
Mauricio Fernandez - http://eigenclass.org - singular Ruby

Better example:

class Child < Parent
  def hoo
    super.zoo
  end
  def zoo
    print "don't want to be here"
  end
end

-- Nate

···

On Thu, 24 Aug 2006, Douglas A. Seifert wrote:

Why would you need to explicitly reference super? It is not necessary:

$ irb
irb(main):001:0> class Parent
irb(main):002:1> def zoo
irb(main):003:2> puts "zoo in Parent!"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0>
irb(main):007:0* class Child < Parent
irb(main):008:1> def hoo
irb(main):009:2> zoo
irb(main):010:2> end
irb(main):011:1> end
=> nil
irb(main):013:0> c = Child.new
=> #<Child:0x39dd78>
irb(main):014:0> c.hoo
zoo in Parent!
=> nil
irb(main):015:0>

A more correct conclusion would have been that Ruby's 'super' should
be regarded more as a method call rather than as a pseudo-variable

yes, super can be seen as a method call.

···

--

Guy Decoux

Morton Goldberg wrote:

A more correct conclusion would have been that Ruby's 'super' should
be regarded more as a method call rather than as a pseudo-variable
(such as 'self'). This is quite different than the 'super' of
Smalltalk and other object-oriented languages I have past experience
with.

Ruby follows Eiffel's lead in this regard.

-- Jim Weirich

···

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

Hi --

···

On Thu, 24 Aug 2006, Nathan Smith wrote:

On Thu, 24 Aug 2006, Douglas A. Seifert wrote:

Why would you need to explicitly reference super? It is not necessary:

$ irb
irb(main):001:0> class Parent
irb(main):002:1> def zoo
irb(main):003:2> puts "zoo in Parent!"
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0>
irb(main):007:0* class Child < Parent
irb(main):008:1> def hoo
irb(main):009:2> zoo
irb(main):010:2> end
irb(main):011:1> end
=> nil
irb(main):013:0> c = Child.new
=> #<Child:0x39dd78>
irb(main):014:0> c.hoo
zoo in Parent!
=> nil
irb(main):015:0>

Better example:

class Child < Parent
def hoo
   super.zoo
end
def zoo
   print "don't want to be here"
end
end

But the Parent class has no hoo instance method, so calling super from
hoo won't work.

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
Ruby for Rails => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.