'ruby: calling super without having a parent class

I have a class which overrides self.new and calls super in it, but the class doesn't derive from antoher class. So what exactly does the call?

class Test
  attr_reader :blatt

  def self.new(blatt, quellformat, &block)
    begin
      # why can't I call initialize(blatt,quellformat) here? 
      # when I try this, it only prints "wrong # of arguments(2 for 1)"

      a = super(blatt, quellformat) # but this works...

      # some code
      a
    end
  end

  def initialize(blatt, quellformat)
    @name = blatt.blattname
    @datei = blatt.datei
    @blatt = blatt
    @qu = quellformat
  end
end


Solution 1:[1]

why can't I call initialize(blatt,quellformat) here?

Because Test::new is a class method and Test#initialize is an instance method. You need an instance of your class to call initialize.

but the class doesn't derive from another class

It might not be obvious, but your class is actually an instance of Class.

So what exactly does the call?

By defining self.new, you're overriding Class#new. According to the documentation:

Calls allocate to create a new object of class’s class, then invokes that object’s initialize method, passing it args.

A Ruby implementation would look like this:

def self.new(*args)
  obj = allocate
  obj.send(:initialize, *args)
  obj
end

Calling super simply invokes the default implementation, i.e. Class#new, which does the same. Here's the C code:

VALUE
rb_class_new_instance(int argc, const VALUE *argv, VALUE klass)
{
    VALUE obj;

    obj = rb_obj_alloc(klass);
    rb_obj_call_init(obj, argc, argv);

    return obj;
}

Solution 2:[2]

Classes inherit from Object by default. Hence, your super call will call Object.new.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2