这看起来像是 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
,一切都是 honky-dory,但一旦它认为是private
,它就失败了。
然而,实际的实现Class#new
看起来更像这样:
class Class
def new(...)
obj = allocate
obj.__send__(:initialize, ...)
obj
end
end
如果我的假设是正确的,那么 Sorbet 中有两个错误通常会相互抵消:
- 的定义
Class#new
是错误的。这意味着你总是会得到一个错误,因为initialize
is always private
,除了
- 的默认可见性
initialize
也是错误的。
但是,我没有检查这些假设,所以我可能会完全放弃。