Это похоже на ошибку в Sorbet, так как initialize
обрабатывается языком особым образом и, таким образом, всегда private
по умолчанию в любом случае. Другими словами, ваш код на 100 % идентичен тому же коду без private
:
# typed: true
class A
extend T::Sig
sig {params(x: Integer).void}
def initialize(x)
end
end
def main
A.new(91)
end
p A.private_instance_methods(false).include?(:initialize)
#=> true
Который успешно проходит проверку типов. а>
Я предполагаю, что Sorbet не знает о специальной обработке initialize
в Ruby и поэтому рассматривает его как обычный метод. Мое второе предположение заключается в том, что Sorbet содержит определение Class#new
, которое выглядит так:
class Class
def new(...)
obj = allocate
obj.initialize(...)
obj
end
end
Это означает, что пока Sorbet думает, что initialize
есть public
, все в порядке, но как только он думает, что это private
, он терпит неудачу.
Однако фактическая реализация Class#new
выглядит примерно так:
class Class
def new(...)
obj = allocate
obj.__send__(:initialize, ...)
obj
end
end
Если мои предположения верны, в Sorbet есть две ошибки, которые обычно компенсируют друг друга:
- Определение
Class#new
неверно. Это означает, что вы всегда будете получать сообщение об ошибке, потому что initialize
всегда равно private
, за исключением
- Видимость по умолчанию для
initialize
также неверна.
Однако я не проверял эти предположения, поэтому могу ошибаться.
person
Jörg W Mittag
schedule
22.12.2020