'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’sinitialize
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 |