How can I resolve sorbet error: "Use of undeclared variable"?
How can I resolve sorbet error: "Use of undeclared variable"?
我正在尝试将冰糕类型信息添加到我的 gem、pdf-reader。我不希望 sorbet 成为 gem 的运行时依赖项,因此所有类型注释都在 rbi/
目录的外部文件中。我也无法在 类.
中扩展 T::Sig
我想在某些文件中启用 typed: strict
,但这样做会表明我正在使用一些没有类型注释的实例变量:
./lib/pdf/reader/rectangle.rb:94: Use of undeclared variable @bottom_left https://srb.help/6002
94 | @bottom_left = PDF::Reader::Point.new(
^^^^^^^^^^^^
./lib/pdf/reader/rectangle.rb:98: Use of undeclared variable @bottom_right https://srb.help/6002
98 | @bottom_right = PDF::Reader::Point.new(
^^^^^^^^^^^^^
./lib/pdf/reader/rectangle.rb:102: Use of undeclared variable @top_left https://srb.help/6002
102 | @top_left = PDF::Reader::Point.new(
^^^^^^^^^
./lib/pdf/reader/rectangle.rb:106: Use of undeclared variable @top_right https://srb.help/6002
106 | @top_right = PDF::Reader::Point.new(
建议的修复方法是使用 T.let()
:
@top_right = T.let(PDF::Reader::Point.new(0,0), PDF::Reader::Point)
但是我不能那样做,因为它需要对冰糕的运行时依赖。
是否可以在 rbi 文件中记录实例变量的注释?
根据 the documentation“RBI 文件的语法与普通 Ruby 文件相同,只是方法定义不需要实现。”因此,在 RBI 文件中声明实例变量类型的语法与 Ruby 文件中的相同:
sig do
params(
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
).void
end
def initialize(x1, y1, x2, y2)
@top_right = T.let(PDF::Reader::Point.new(0,0), PDF::Reader::Point)
# …
end
另一种方法是使用 RBS 语法而不是 RBI 语法,它本身支持实例变量的类型注释。但是,我在 Sorbet 中发现了关于 RBS 支持的相互矛盾的信息。网上声称 Sorbet 支持 RBS。 OTOH,the Sorbet FAQ 用将来时谈论 RBS 支持。另一方面,other,FAQ 中提到的“未来”是 Ruby 3 的发布,这实际上是过去一年。
在 RBS 中,它看起来像这样:
module PDF
class Reader
@top_left: Numeric
@top_right: Numeric
@bottom_left: Numeric
@bottom_right: Numeric
class Rectangle
def initialize: (
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
) -> void
end
end
end
或者,因为它们也是 attr_reader
,所以只做
可能就足够了
module PDF
class Reader
attr_reader top_left: Numeric
attr_reader top_right: Numeric
attr_reader bottom_left: Numeric
attr_reader bottom_right: Numeric
class Rectangle
def initialize: (
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
) -> void
end
end
end
我相信,这样也会隐式类型对应的实例变量,不过我没测试过这个
我正在尝试将冰糕类型信息添加到我的 gem、pdf-reader。我不希望 sorbet 成为 gem 的运行时依赖项,因此所有类型注释都在 rbi/
目录的外部文件中。我也无法在 类.
T::Sig
我想在某些文件中启用 typed: strict
,但这样做会表明我正在使用一些没有类型注释的实例变量:
./lib/pdf/reader/rectangle.rb:94: Use of undeclared variable @bottom_left https://srb.help/6002
94 | @bottom_left = PDF::Reader::Point.new(
^^^^^^^^^^^^
./lib/pdf/reader/rectangle.rb:98: Use of undeclared variable @bottom_right https://srb.help/6002
98 | @bottom_right = PDF::Reader::Point.new(
^^^^^^^^^^^^^
./lib/pdf/reader/rectangle.rb:102: Use of undeclared variable @top_left https://srb.help/6002
102 | @top_left = PDF::Reader::Point.new(
^^^^^^^^^
./lib/pdf/reader/rectangle.rb:106: Use of undeclared variable @top_right https://srb.help/6002
106 | @top_right = PDF::Reader::Point.new(
建议的修复方法是使用 T.let()
:
@top_right = T.let(PDF::Reader::Point.new(0,0), PDF::Reader::Point)
但是我不能那样做,因为它需要对冰糕的运行时依赖。
是否可以在 rbi 文件中记录实例变量的注释?
根据 the documentation“RBI 文件的语法与普通 Ruby 文件相同,只是方法定义不需要实现。”因此,在 RBI 文件中声明实例变量类型的语法与 Ruby 文件中的相同:
sig do
params(
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
).void
end
def initialize(x1, y1, x2, y2)
@top_right = T.let(PDF::Reader::Point.new(0,0), PDF::Reader::Point)
# …
end
另一种方法是使用 RBS 语法而不是 RBI 语法,它本身支持实例变量的类型注释。但是,我在 Sorbet 中发现了关于 RBS 支持的相互矛盾的信息。网上声称 Sorbet 支持 RBS。 OTOH,the Sorbet FAQ 用将来时谈论 RBS 支持。另一方面,other,FAQ 中提到的“未来”是 Ruby 3 的发布,这实际上是过去一年。
在 RBS 中,它看起来像这样:
module PDF
class Reader
@top_left: Numeric
@top_right: Numeric
@bottom_left: Numeric
@bottom_right: Numeric
class Rectangle
def initialize: (
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
) -> void
end
end
end
或者,因为它们也是 attr_reader
,所以只做
module PDF
class Reader
attr_reader top_left: Numeric
attr_reader top_right: Numeric
attr_reader bottom_left: Numeric
attr_reader bottom_right: Numeric
class Rectangle
def initialize: (
x1: Numeric,
y1: Numeric,
x2: Numeric,
y2: Numeric
) -> void
end
end
end
我相信,这样也会隐式类型对应的实例变量,不过我没测试过这个