【发布时间】:2022-01-18 02:29:59
【问题描述】:
我维护 pdf-reader ruby gem,并且正在尝试通过 sorbet 进行静态类型检查。
我有一个particular source file,目前是typed: false,我想将其更改为typed: true。当我这样做时,冰糕抱怨这种状态机形状的方法:
def process_data(data)
parser = build_parser(data)
mode = :none
instructions = []
while token = parser.parse_token(CMAP_KEYWORDS)
if token == "beginbfchar"
mode = :char
elsif token == "endbfchar"
process_bfchar_instructions(instructions)
instructions = []
mode = :none
elsif token == "beginbfrange"
mode = :range
elsif token == "endbfrange"
process_bfrange_instructions(instructions)
instructions = []
mode = :none
elsif mode == :char || mode == :range
instructions << token
end
end
end
我收到此错误:
$ srb tc
./lib/pdf/reader/cmap.rb:74: This code is unreachable https://srb.help/7006
74 | elsif mode == :char || mode == :range
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
./lib/pdf/reader/cmap.rb:74: This condition was always falsy (T::Boolean)
74 | elsif mode == :char || mode == :range
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Got T::Boolean originating from:
./lib/pdf/reader/cmap.rb:74:
74 | elsif mode == :char || mode == :range
^^^^^^^^^^^^^
./lib/pdf/reader/cmap.rb:75: This code is unreachable https://srb.help/7006
75 | instructions << token
^^^^^^^^^^^^^^^^^^^^^
./lib/pdf/reader/cmap.rb:74: This condition was always falsy (T::Boolean)
74 | elsif mode == :char || mode == :range
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Got T::Boolean originating from:
./lib/pdf/reader/cmap.rb:74:
74 | elsif mode == :char || mode == :range
我相当有信心 sorbet 认为无法在生产环境中执行的代码。如果是这种情况,此类将无法工作。
大概有一些关于这个代码结构或类型注释的东西让 sorbet 相信mode 永远不会等于:char 或:range。到目前为止,我还无法解决它。我错过了什么?
【问题讨论】:
-
您最初设置了
mode = :none,因此 sorbet 可能会得出结论,它不能等于:char,因为它没有考虑到while循环。