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

On 23/08/06, Bart B. [email protected] wrote:

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 Aug 23, 2006, at 10:30 AM, Bart B. wrote:

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 G. II

Julian ‘Julik’ Tarkhanov wrote:

On 23-aug-2006, at 17:39, James Edward G. 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) )

On 23-aug-2006, at 17:39, James Edward G. 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.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.

To satisfy your curiosity,

#! /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

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

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

Regards, Morton

On Thu, 24 Aug 2006, William C. wrote:

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

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.

Nathan S. wrote:

Actually I am curious to know:
class Child < Parent
end
I think he’s wanting to know if it’s possible to call a different method
super.zoo
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

“M” == Morton G. [email protected] writes:

M> From which I conclude that ‘super.another’ is parsed as ‘super
M> 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

Julian ‘Julik’ Tarkhanov wrote:

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 Aug 23, 2006, at 11:11 AM, Nathan S. 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

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 G. II

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

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

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 8/23/06, Douglas A. Seifert [email protected] wrote:

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.

Hi –

On Thu, 24 Aug 2006, Nathan S. wrote:

=> nil
zoo in Parent!
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

Hi –

On Thu, 24 Aug 2006, Mauricio F. wrote:

if self.class.instance_methods(false).include? meth.to_s

end
end

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

END

>> Hello from Parent!

>> Hello from Child!

This only works for superclasses, I think, whereas super just looks
higher up in the method lookup chain, in modules as well as classes.

I’m thinking of, for example:

class A
def x
puts “A#x”
end
end

module M
def x
puts “M#x”
end
def y
send_super(:x)
end
end

a = A.new
a.extend(M)

a.x
a.y

So… maybe this:

Sigh – Matz, please can we have this? :slight_smile:

def singleton_class
class << self; self; end
end

def send_super(meth, *args, &b)
m = singleton_class.ancestors[1…-1].find {|a|
a.instance_methods(false).include?(meth.to_s)}
m.instance_method(meth).bind(self).call(*args, &b)
end

David

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

“M” == Morton G. [email protected] writes:

M> From which I conclude that ‘super.another’ is parsed as ‘super
M> 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

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:

#! /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

Child something Parent something Child another

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 Thu, 24 Aug 2006 [email protected] wrote:

irb(main):002:1> def zoo
=> nil
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.

Exactly! That’s the point I was getting at. It’d be nice if this would
work. “self” points to the object who’s method the interpreter is in, so
playing by that same game, “super” should point to the superclass of the
object who’s method the interpreter is in.

Nate

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

irb(main):007:0* class Child < Parent
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

– Nate

On Aug 23, 2006, at 3:13 PM, [email protected] wrote:

Sigh – Matz, please can we have this? :slight_smile:

def singleton_class
class << self; self; end
end

I have never before given my opinion on this issue, so I think I’ll
take this chance to do so. After this message, I promise to shut up
about it.

I agree that singleton_class() should be added to the language.

Here’s the pros and cons as I understand them:

Pros

  • Internally, this is what Ruby calls the class in question
  • The C API uses this name all over the place
  • Documentation and many books refer to the class as such
  • Matz’s use of the term predates the design pattern usage
  • Anyone learning singleton class functionality is smart enough to
    keep it straight from the design pattern of the same name
  • None of the other suggestions seems to have won over the masses
  • We would have an official name to refer to this concept

Cons

  • It conflicts with a popular design pattern

To me, the choice is pretty obvious. It’s not like it’s the first
overloaded term in computing history or anything.

OK, I’ve said my peace. Thanks for listening.

James Edward G. II