Call functions of superclass

B

Bart Braem

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
 
F

Farrel Lifson

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
 
J

James Edward Gray II

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. ;)

James Edward Gray II
 
J

Julian 'Julik' Tarkhanov

Try the correction above. ;)

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.
 
W

William Crawford

Julian said:
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) )
 
N

Nathan Smith

super # call _another_ instance method BUT of the

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
 
M

Morton Goldberg

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
 
D

Douglas A. Seifert

Nathan said:
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
 
I

Isak

Julian said:
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 :eek:ld_another :another
def another
# overriding the old one
end
end


Isak
 
W

William Crawford

Douglas said:
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.
 
T

ts

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
 
J

James Edward Gray II

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 Gray II
 
J

Jan Svitok

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.
 
M

Mauricio Fernandez

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

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!
 
N

Nathan Smith

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


-- Nate
 
D

dblack

Hi --

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
http://www.manning.com/black => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.
 
D

dblack

Hi --

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!

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? :)
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

--
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
http://www.manning.com/black => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.
 
M

Morton Goldberg

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:

<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
 
N

Nathan Smith

Hi --



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
 
J

James Edward Gray II

# Sigh -- Matz, *please* can we have this? :)
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 Gray II
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,130
Latest member
MitchellTe
Top