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

为Ruby Gem添加RBS时,如何处理可选Block的类型校验问题

解决RBS可选Block的类型校验问题

问题场景

现有Ruby方法:

def some_method(&block)
   if block
      foo = block.call
   end
end

对应的RBS签名:

def some_method: () ?{ () -> String } -> void

执行steep check时触发错误:

[error] Type nil does not have method call
│ Diagnostic ID: Ruby::NoMethod
│
└ foo = block.call
~~~~

需要保留&block为可选参数,且不修改原有代码逻辑,解决类型校验错误。

解决方案

方案1:添加Steep类型断言注释

在if block分支内添加类型注释,明确告知Steep该分支中block不为nil,无需修改业务逻辑代码:

def some_method(&block)
   if block
      # @type var block: () -> String
      foo = block.call
   end
end

Steep会识别该注释,在分支内将block的类型细化为非nil的Proc类型,消除错误。

方案2:使用RBS重载签名

将原RBS签名拆分为两个重载,分别对应“不带block”和“带block”的场景:

def some_method: () -> void
def some_method: () { () -> String } -> void

这种写法会让Steep根据调用时是否传入block匹配对应的签名,if block分支只会在带block的签名下触发,自然不会出现nil调用call的错误。

内容的提问来源于stack exchange,提问作者Paul W

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 02:55:00