Access surrounding class

Hello,

is there a possibility in ruby to access the surrounding runtime
type from within a nested class? Module.nesting is not sufficient,
because it relies on definition time:

Following scenario:
------------------snip-----------------------
class A
class C
def a
puts …::type #access surrounding class
end
end
end
class B < A
end
------------------snap-----------------------

How to do that?

I thought about constants:
class A
CONST=A
end
class B < A
CONST=B
end
or even methods, that get refined in specialising classes,
but all solutions have the same problem: The access of the
runtime type of the surrounding class.

Is there any suggestion or idea, to solve this problem??

Best regards,
Matthias

···

A::C.new.a should print “A”, B::C.new.a should print “B”.


Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free
http://sbc.yahoo.com

Following scenario:

Well, I've not understood what you want to do but try this

pigeon% cat b.rb
#!/usr/bin/ruby
class A
   class C
   end
end
class B < A
   def b
      puts "b"
   end
end

B::C.new.b
pigeon%

pigeon% b.rb
./b.rb:12: undefined method `b' for #<A::C:0x401ad694> (NameError)
pigeon%

The class of the new object is A::C, even if you call B::C::new

Guy Decoux

Matthias, can you describe your problem at a higher level?

This seems funky – maybe there’s a better approach?

  • Ryan King

Matthias, can you describe your problem at a higher level?

This seems funky – maybe there’s a better approach?

  • Ryan King

Sorry for my stumbled sentences - I try again.

In specializing classes I can refine methods:

class A
def doit
puts “bla”
end
end
class B < A
def doit
puts “foo”
end
end
A.new.doit
B.new.doit

will print:
bla
foo

as expected. If I define a class inside A, use functionality
from A (which must be static), I can not refine this
functionality:

class A
def self.doit
puts “bla”
end
class Inner
def a
A.doit
end
end
end
class B < A
def self.doit
puts "foo:
end
end
B::Inner.new.a

will print:
bla
bla

If I could express something like .doit that would
be defined in A and is refineable. I do not know, if there is
such a construct - I think not.
But perhaps there is a simple solution to circumvent the absolute
path to make this work??

Hope this was more expressive… :slight_smile:

Matthias

···

RK == Ryan King rking@panoptic.com wrote:
A::Inner.new.a


Do You Yahoo!?
Sign up for SBC Yahoo! Dial - First Month Free

class A
def self.doit
puts “bla”
end
class Inner
def a
A.doit
end
end
end
class B < A
def self.doit
puts "foo:
end
end
A::Inner.new.a
B::Inner.new.a

will print:
bla
bla

If I could express something like .doit that would
be defined in A and is refineable. I do not know, if there is
such a construct - I think not.
But perhaps there is a simple solution to circumvent the absolute
path to make this work??

Try this:

class A
def self.doit
puts “bla”
end

class Inner
def outer
cls = self.class.to_s.split(/::/)[-2]
Module.const_get(cls)
end

def a
  outer.doit
end

end
end

class B < A
def self.doit
puts “foo”
end

class Inner < A::Inner
end
end

B::Inner.new.a

bla
foo

You still need to declare Inner inside B somehow, i.e. apparently
inheriting will bring A’s methods into subclass but not A’s inner
classes.

HTH

Massimiliano

···

On Tue, Oct 15, 2002 at 01:41:47AM +0900, Matthias Veit wrote:
A::Inner.new.a