Knowing which subclass called a superclass class method

Hi All,

  If I have class A and class B, and they both inherit from S.
  And in S there is a class method called doSomething.

  How do I know in S's doSomething wether it was called like:

  A.doSomething

  or

  B.doSomething

  thanks,

  Rob

···

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

Rob Boellaard wrote:

  If I have class A and class B, and they both inherit from S.
And in S there is a class method called doSomething.

How do I know in S's doSomething wether it was called like:

A.doSomething

or

B.doSomething

self will be A or B.

HTH,
Sebastian

···

--
NP: Dark Suns - Infiltration
Jabber: sepp2k@jabber.org
ICQ: 205544826

self will be A or B.

  thanks for the quick reply Sebastian.

  I was trying to get the class name into a string.

   self.class.to_s

  gave me Class

  however,

    self.to_s

  indeed gave me S

  regards

  Rob

···

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

Sebastian Hungerecker wrote:

Rob Boellaard wrote:

  If I have class A and class B, and they both inherit from S.
And in S there is a class method called doSomething.

self will be A or B.

self.class.name will == 'A' or 'B'

No, self.name will be "A" or "B" - self.class.name is "Class". Remember, we are talking about a class method.

irb(main):001:0> class Base
irb(main):002:1> def self.x
irb(main):003:2> [self.class.name, self.name]
irb(main):004:2> end
irb(main):005:1> end
=> nil
irb(main):006:0> class A<Base;end
=> nil
irb(main):007:0> class B<Base;end
=> nil
irb(main):008:0> A.x
=> ["Class", "A"]
irb(main):009:0> B.x
=> ["Class", "B"]
irb(main):010:0>

I would not use the name but rather self (the class object) itself if I would want to do some class specific stuff, but:

Tip: Using this information, such as in an 'if' statement, leads to bad
design. The purpose of OO programming is polymorphism. A and B should have
derived methods that doSomething calls. That's the Abstract Template
pattern.

Absolutely agree.

Kind regards

  robert

···

On 14.06.2008 19:38, Phlip wrote:

to continue on the same theme, if this is the class:

class S

puts "1" + self

    def self.doSomething
        puts "2" + self
    end

end

I get:

1 S
2 A

  why is there this difference? and is there a way to get A in the first
case?

  thanks in advance

  Rob

···

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

Hi --

to continue on the same theme, if this is the class:

class S

puts "1" + self

   def self.doSomething
       puts "2" + self

Do you mean self.name, in both cases?

   end

end

I get:

1 S
2 A

I assume that you've done:

   class A < S
   end

   A.doSomething # or do_something, using Ruby style naming

and that you didn't really get magically-inserted spaces :slight_smile:

why is there this difference? and is there a way to get A in the first
case?

The code inside a class definition gets executed when the class
definition is read in. Code at the top level of the definition, like
your puts statement, gets executed right away. Method definitions get
executed in the sense that the methods get defined, but the methods
themselves don't get executed until they're called.

So your definition of S does two things:

   * prints out "1" + self.name
   * defines a method, to be called later

If you want to do the puts'ing for a subclass, you could do:

   class S
     def self.inherited(c)
       c.class_eval { puts "1" + self.name }
     end
   end

(or just puts "1" + c.name)

David

···

On Sun, 15 Jun 2008, Rob Boellaard wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   ADVANCING WITH RAILS June 16-19 Berlin
   ADVANCING WITH RAILS July 21-24 Edison, NJ
See http://www.rubypal.com for details and updates!

Hi David,

  This time I really made the class :wink:

class S

attr_accessor :my_ivar

    def self.inherited(c)
         c.class_eval {
           @my_ivar = self.name
         }

    end

  def initialize
    puts "In S initialize, my_ivar = #{@my_ivar}"
    super
  end

  def self.do_something
    puts "In S class-method do_something, my_ivar = #{@my_ivar}"
  end

end

and,

require "s"

class B < S

  def initialize
    super
  end

  def show_my_ivar

    puts "In show_my_ivar " + @my_ivar
  end

end

when I do B.do_something, @my_ivar is "B" as it should
but if I do B.new, my_ivar is nil

  To solve it I can modify initialize like:

  def initialize
      @my_ivar = self.class.to_s
    puts "In S initialize, my_ivar = #{@my_ivar}"
    super
  end

and
b = B.new
puts b.show_my_ivar

works properly.

But as this is a simplification, in my real app I need a few lines of
code to set @my_ivar, and I 'd rather not have too much duplicate code.

  I guess what I am trying for is to configure a variable, using the
name of the subclass, that is readily available to both class methods
and instance methods.

  thanks a lot,

  Rob

···

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