Following code is just a simple simulation, the really code is more complex, even recursively, make set @root value directly in initialize is almost not possible.
class A
@root : String
def initialize
calculate
end
def calculate
# here we have complicated logic to ensure @root is exists before use it.
@root = "/home"
end
end
a = A.new
Error: instance variable '@root' of A was not initialized directly in all of the 'initialize' methods, rendering it nilable. Indirect initialization is not supported.
Assuming there’s some reason you can’t directly set @root = "/home" in the initialize method, you could turn calculate into a macro instead, and have that code embedded into your initialize call instead?
Another option would be to turn the type of @root into String? instead, and then define a custom getter that only returns String and use that in your code instead of @root directly. i.e.:
@root : String? = nil
private def root
@root || raise "Root is nil! This shouldn't be called, unless calculate has a bug because it's overly complicated"
end
def my_recursive_method(...)
# use `root` instead of `@root` here
end