Calling shadowed methods in an inherited object

If I have code like:

class A
def foo
puts "A::foo"
end
end

class B < A
def foo
puts "B::foo"
end
def bar
# call A::foo
end
end

Is there a legal way to call A::foo from B::bar?

I would have thought that super gave access to the scope of the parent for
function calls, but I guess it only acts this way for methods named the same as
the current caller. So is there a way todo something like

super.foo #-> “A::foo”

from bar?

I thought I read somewhere that you could but it’s possible i am confusing ruby
with another language.

Thanks,

Charlie

Charles Comstock wrote:

If I have code like:

class A
def foo
puts “A::foo”
end
end

class B < A
def foo
puts “B::foo”
end
def bar
# call A::foo
end
end

Is there a legal way to call A::foo from B::bar?

I would have thought that super gave access to the scope of the parent for
function calls, but I guess it only acts this way for methods named the same as
the current caller. So is there a way todo something like

super.foo #-> “A::foo”

from bar?

I thought I read somewhere that you could but it’s possible i am confusing ruby
with another language.

Thanks,

Charlie

There is a way, and it’s ugly, but it goes something like this:

def bar
A.instance_method( :foo ).bind( self ).call
end

In other words, you get the unbound version of ‘foo’ from A, bind it to
the current instance of B, and invoke it. If there is a cleaner way, I
don’t know it, but would love to hear about it.

···


Jamis Buck
jgb3@email.byu.edu

ruby -h | ruby -e ‘a=;readlines.join.scan(/-(.)[e|Kk(\S*)|le.l(…)e|#!(\S*)/) {|r| a << r.compact.first };puts “\n>#{a.join(%q/ /)}<\n\n”’

Charles Comstock wrote:

If I have code like:

class A
def foo
puts “A::foo”
end
end

class B < A
def foo
puts “B::foo”
end
def bar
# call A::foo
end
end

Is there a legal way to call A::foo from B::bar?
snip

There is a way, and it’s ugly, but it goes something like this:

def bar
A.instance_method( :foo ).bind( self ).call
end

In other words, you get the unbound version of ‘foo’ from A, bind it to
the current instance of B, and invoke it. If there is a cleaner way, I
don’t know it, but would love to hear about it.

Gah that’s nasty. You can get the superclass automatically with

self.class.superclass

so I guess you can do it with

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

so I wonder if there is a way to make a singleton or temporary class
which could be returned by say parent allowing you to just use

parent.foo

to just do all of above. Clearly this doesn’t seem to be something
that is supposed to be easy. Perhaps someone knows why?

Thanks for the help anyway,

Charlie

···

On Tue, 6 Jan 2004, Jamis Buck wrote:

“Charles Comstock” cc1@cec.wustl.edu schrieb im Newsbeitrag
news:Pine.LNX.4.44.0401052300530.25734-100000@earwig.int.cec.wustl.edu…

Gah that’s nasty. You can get the superclass automatically with

self.class.superclass

so I guess you can do it with

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

so I wonder if there is a way to make a singleton or temporary class
which could be returned by say parent allowing you to just use

parent.foo

to just do all of above. Clearly this doesn’t seem to be something
that is supposed to be easy. Perhaps someone knows why?

How about defining a method in Object?

irb(main):001:0> class Object
irb(main):002:1>
irb(main):003:1* def super_call( sym, args )
irb(main):004:2> self.class.superclass.instance_method(
sym ).bind(self).call(args)
irb(main):005:2> end
irb(main):006:1>
irb(main):007:1
end
=> nil
irb(main):008:0>
irb(main):009:0
class Test
irb(main):010:1> def foo; puts “Test”; end
irb(main):011:1> end
=> nil
irb(main):012:0>
irb(main):013:0* class Test2 < Test
irb(main):014:1> def foo; puts “Test2”; end
irb(main):015:1> end
=> nil
irb(main):016:0>
irb(main):017:0* Test2.new.super_call( :foo )
Test
=> nil
irb(main):018:0>
irb(main):019:0*

Cheers

robert