使用Sorbet扩展Array方法遇Elem未定义错误,如何引入对应RBI?
问题解决方法
你遇到的Array::Elem未定义错误,核心原因是Elem是Sorbet为Array在RBI文件中声明的静态类型参数,仅用于静态类型检查,运行时并不存在这个常量。直接在代码中引用Elem会导致运行时找不到该常量。
修正步骤:
- 正确引用Array的泛型参数:
Array本身是泛型类,已经定义了名为:Elem的类型参数,在方法签名中需要通过T.type_parameter(:Elem)来引用它,而非直接写Elem。 - 修正返回类型:
你的split_on方法返回的是「原数组元素组成的数组的数组」,所以返回类型应该是T::Array[T::Array[T.type_parameter(:Elem)]],而非原来的T::Array[Elem]。
修正后的完整代码:
require 'sorbet-runtime' class Array extend T::Sig extend T::Generic sig do type_parameters(:U) .params(split_elem: T.type_parameter(:U)) .returns(T::Array[T::Array[T.type_parameter(:Elem)]]) end def split_on(split_elem) output = [] group = [] each do |elem| if elem.eql?(split_elem) output << group unless group.empty? group = [] else group << elem end end output << group unless group.empty? output end end
额外说明:
- 不需要显式引入RBI文件,Sorbet在静态检查时会自动读取标准库的RBI,而运行时
sorbet-runtime只处理必要的泛型逻辑,不会保留Elem这类静态类型常量。 - 确保已经正确安装并引入
sorbet-runtime(代码开头的require 'sorbet-runtime'不能少)。
内容的提问来源于stack exchange,提问作者fre
相关产品推荐
相关产品推荐

