diedthreetimes
diedthreetimes

Reputation: 4115

Calling super from a class method

When redefining a class method I want to be able to call super, just as I would in a instance method.

For example, I have a class hi with a class method Hi.hi

class Hi
  def self.hi
    puts "hi"
  end
end

Hi.hi #=> "hi"

Now, Lets say i want to redefine self.hi

class Hi
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi #=> NoMethodError: super: no superclass method `hi' for Hi:Class

Why doesn't this work?

I know I can get the same functionality using alias (as below), it just seems rather unnecessary.

class Hi
  class << self
    def new_hi
      old_hi
      puts "Oh!"
    end
    alias :old_hi :hi
    alias :hi :new_hi 
  end
end

Hi.hi #=> "hi\n Oh!"

Is there a better way to do this?

Upvotes: 5

Views: 4600

Answers (4)

Vadim Golub
Vadim Golub

Reputation: 1755

Super works for child classes inherited from a parent class.

In your case alias is the only way. Or you can use alias_method:

alias_method :old_hi, :hi

def self.hi
  old_hi
  puts "Oh!"
end

Upvotes: 4

Fab
Fab

Reputation: 665

In the context of your code "super" refers to the Object class, since Object doesn't have a "hi" class level method it fails. "Hi" is an object of type "Class".

You don't have a super class defined so it defaults to object. You can see this at the console by typing "Hi.superclass"

The better way is to use traditional OOP to do this:

class Hi
  def self.hi
    puts "hi"
  end
end

class Ho < Hi
  def self.hi
    super
    puts "Oh!"
  end
end

The "class << self" syntax ends up creating an invisible intermediate class which does the inheritance chain.

It shouldn't matter that you created a new class since the new class extends the old one, they are interchangeable, except for the different output of self.hi()

Upvotes: 2

knut
knut

Reputation: 27855

I don't understand your problem.

If you really redefine self.hi (Saying: super has a hi), then it works:

class Hi_super
  def self.hi
    puts "Oh - super!"
  end
end


class Hi < Hi_super
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi

Or in another version:

class Object
  def self.hi
    puts "Oh - super!"
  end
end


class Hi 
  def self.hi
    super
    puts "Oh!"
  end
end

Hi.hi

Both version s results in

Oh - super!
Oh!

Upvotes: 0

user744186
user744186

Reputation:

It does not work.Because the ancestors for your class Hi don't have a method hi.

Upvotes: 0

Related Questions