abstract class Component
protected getter parent : Component
def initialize(@parent)
end
end
class SomethingReal1 < Component
property title : String
def initialize
# OK no error here - super at the end
@title = "title"
super self
end
end
class SomethingReal2 < Component
property title : String
def initialize
# ERROR in this constructor - super at the begin
# Error: instance variable '@title' of SomethingReal2 was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported.
super self
@title = "title"
end
end
I didn’t understand for about 2 hours why my SomethingReal2 class init wasn’t working - I have to call super (superclass initializer) as the last call. Ugh…
Why please? I can’t find anything in the doc. Why I need to set first all instvars from the subclass and then call superclass initializer? Is it a bug?
abstract class Component
protected getter parent : Component
def initialize(@parent)
end
end
class SearchField < Component
property search_string = ""
end
class SomethingReal < Component
property title : String
property search_field : SearchField
def initialize
@title = "title"
@search_field = SearchField.new self
super self
end
end
pp SomethingReal.new
when I need to send self in SomethingReal#initialize component as parent to the initilalization of @search_field component?
A possible solution is to make the ivar nilable. That allows you to initialize its value later.
Together with a non-nilable getter (e.g. property!), using it should be simple and safe.
abstract class Component
protected getter parent : Component
def initialize(@parent)
end
end
class SearchField < Component
property search_string = ""
end
class SomethingReal < Component
property title : String
property! search_field : SearchField
def initialize
@title = "title"
super self
@search_field = SearchField.new self
end
end
pp SomethingReal.new
Yeah, but it’s “raise-on-nil” getter - you get the error “later” in the runtime (if you forget to create it in the constructor) - which may be too late for someone’s taste.