if initialize of a class and it's parent have the same signature, super can be used without explicitly passing the arguments.
However if they take only a block argument, and you do not pass it explicitly, initialize of the parent class is never called, which easily leads to a segfault.
Sample
class A
@proc : ->
@num : Int64
def initialize(&b)
puts "A initialised" # not executed
@proc = ->{}
@num = 123456789
end
end
class B < A
def initialize(&b)
super # adding &b here removes the issue
puts @num # @num is 0
@proc.call # tries to read null pointer and crashes
end
end
b = B.new { }
this is the backtrace:
[0x10bc628cb] *Exception::CallStack::print_backtrace:Nil +107 in /Users/xxx/.cache/crystal/crystal-run-test.tmp
[0x10bc476ed] ~procProc(Int32, Pointer(LibC::SiginfoT), Pointer(Void), Nil)@/usr/local/Cellar/crystal/1.12.2/share/crystal/src/crystal/system/unix/signal.cr:143 +285 in /Users/zxdx/.cache/crystal/crystal-run-test.tmp
[0x7ff81919437d] _sigtramp +29 in /usr/lib/system/libsystem_platform.dylib
Update
For some reason, adding a second argument to the initialize functions instead causes a strange compile error:
class A
def initialize(a, &b)
end
end
class B < A
def initialize(a, &b)
super
end
end
b = B.new { }
with the error being
14 | super # adding &b here STIL
^----
Error: wrong number of arguments for 'Reference#initialize' (given 1, expected 0)
Overloads are:
- Reference#initialize()
Bug
if
initialize
of a class and it's parent have the same signature,super
can be used without explicitly passing the arguments. However if they take only a block argument, and you do not pass it explicitly,initialize
of the parent class is never called, which easily leads to a segfault.Sample
this is the backtrace:
Update
For some reason, adding a second argument to the
initialize
functions instead causes a strange compile error:with the error being
Version info
OS: macOS 14.1.1 (Sonoma)