If we explicit use self to call methods in the constructor from our own class the compiler believes we are passing self around and make all instance variables nilable. This would be ok if we didn't have the choice of hide the self. from the call and make the program behave differently.
class A
def initialize
self.foo
@bar = 23 # Will be (Int32 | Nil) but self was used just to call
end
def foo
42
end
end
If this is intentional it's weird, Crystal hide the self because it isn't Python :-).
And will be harder to explain someone that the code bellow behaves differently from the one above.
class A
def initialize
foo
@bar = 23 # @bar is Int32.
end
def foo
42
end
end
P.S.: I triggered this on the following use case: I needed to use the self. just to disambiguate a variable name from a existing method.
Tested with Crystal 0.34 on Archlinux.
For simplicity, whenever you use self the compiler will consider every subsequent instance var as nilable. Changing this is pretty hard. You can move 42 to a constant.
I would imagine this is far from trivial to fix. And this 42 was there just as a dummy example.
But IMO this still a bug since we have the same code, different only by making a implicit variable explicit, with different behavior.
My first suggestion (not thinking about all possible side effects) would be to just avoid this check if self is used as a receiver in a method call, since such code can be written without the word "self" and the current compiler allows it.
I'll leave this open. I guess it should be consistently erroring or working.
Most helpful comment
I'll leave this open. I guess it should be consistently erroring or working.