You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在仅用RBI文件存储类型信息的Ruby gem中如何处理Sorbet报错

关于仅用RBI存储类型信息的合理性

你的做法完全没有问题。Sorbet原生支持将所有类型声明统一存放在顶层rbi/目录下的*.rbi文件中,不需要在业务源码里引入任何Sorbet相关的语法或依赖,下游用户如果不使用Sorbet,完全感知不到这些类型文件的存在,不会给他们带来任何额外负担,完全匹配你的需求。

保留运行时校验且避免Sorbet报错的方案

不需要全局禁用7006错误,也不需要删除运行时校验,有两种低成本方案可选:

  1. 单行错误忽略:直接在触发报错的代码行末尾添加Sorbet专属忽略注释即可,仅屏蔽当前行的7006错误,不会影响其他代码的检查,是最符合你需求的方案:
    def initialize(runs, mediabox)
      raise ArgumentError, "a mediabox must be provided" if mediabox.nil? # srb: ignore 7006
    end
    
    这个方案不需要修改任何业务逻辑,添加的注释对运行时没有任何影响,也不需要引入Sorbet运行时依赖。
  2. 用T.unsafe包裹校验对象:如果不介意在源码里出现极少量Sorbet相关代码,可以将校验的对象用T.unsafe包裹,让Sorbet跳过对该对象的类型推导,就不会判定条件永远为假:
    def initialize(runs, mediabox)
      raise ArgumentError, "a mediabox must be provided" if T.unsafe(mediabox).nil?
    end
    
    如果担心T不存在导致运行时报错,可以提前在gem的入口文件里加个fallback定义,不需要完整引入sorbet-runtime:
    # 放在gem入口最顶部,仅当没有加载sorbet-runtime时生效
    unless defined?(T)
      T = Module.new do
        def self.unsafe(obj)
          obj
        end
      end
    end
    

关于是否要移除运行时校验

Sorbet官方从来没有要求公共库移除运行时校验,反而非常鼓励公共库保留必要的运行时参数校验:Sorbet的静态检查仅能覆盖使用了Sorbet的下游用户,对于没有启用Sorbet的下游用户,静态类型约束完全不生效,运行时校验是保障gem鲁棒性的必要手段,完全不需要移除。

内容的提问来源于stack exchange,提问作者James Healy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:15:10