运行 srb rbi 隐藏定义给出了不清楚的错误
Running srb rbi hidden-definitions gives unclear error
上下文
- 我们的团队最近升级到 rails 6(从 5.2)。据我所知,到那时为止一切都运行良好。
- 我们的文件结构有点不寻常,所以我们选择使用
:classic
rails 加载程序而不是 :zeitwerk
问题
每当我们 运行 srb rbi hidden-definitions
现在我们得到以下内容:
Got LoadError when trying to get nested name Tilt::PandocTemplate
Got LoadError when trying to get nested name Tilt::AsciidoctorTemplate
Got LoadError when trying to get nested name Tilt::CreoleTemplate
Got LoadError when trying to get nested name Tilt::LessTemplate
Got LoadError when trying to get nested name Tilt::LiquidTemplate
Got LoadError when trying to get nested name Tilt::LiveScriptTemplate
Got LoadError when trying to get nested name Tilt::MarkabyTemplate
Got LoadError when trying to get nested name Tilt::PrawnTemplate
Got LoadError when trying to get nested name Tilt::RadiusTemplate
Got LoadError when trying to get nested name Tilt::RedClothTemplate
Got LoadError when trying to get nested name Tilt::RstPandocTemplate
Got LoadError when trying to get nested name Tilt::TypeScriptTemplate
Got LoadError when trying to get nested name Tilt::WikiClothTemplate
Got LoadError when trying to get nested name Tilt::YajlTemplate
Naming WebConsoleGot NameError when trying to get nested name WebConsole::SourceLocation_
Generating /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi with 20603 modules and 305 aliases
Printing your code's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/from-source.json
Printing /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json
Traceback (most recent call last):
5: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:237:in `<main>'
4: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:224:in `main'
3: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:232:in `block in make_step'
2: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:38:in `main'
1: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:47:in `main'
/usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:151:in `write_constants': /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi had unexpected errors. Check this file for a clue: /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json.err (RuntimeError)
reflection.json.err(错误指向的地方)散落着无数错误,看起来都像这样:
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707623: dynamic constant assignment https://srb.help/2001
707623 | REFERENCE = ::T.let(nil, ::T.untyped)
^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707624: dynamic constant assignment https://srb.help/2001
707624 | SETUTITSBUS = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707625: dynamic constant assignment https://srb.help/2001
707625 | SLAICEPS = ::T.let(nil, ::T.untyped)
^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707626: dynamic constant assignment https://srb.help/2001
707626 | SPECIALS = ::T.let(nil, ::T.untyped)
^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707627: dynamic constant assignment https://srb.help/2001
707627 | SUBSTITUTES = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707628: dynamic constant assignment https://srb.help/2001
707628 | VALID_CHAR = ::T.let(nil, ::T.untyped)
^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707629: dynamic constant assignment https://srb.help/2001
707629 | VALID_XML_CHARS = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707618: class definition in method body https://srb.help/2001
707618 |class REXML::Text < REXML::Child
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707801: class definition in method body https://srb.help/2001
707801 |class REXML::UndefinedNamespaceException < REXML::ParseException
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707813: module definition in method body https://srb.help/2001
707813 |module REXML::Validation
^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707817: class definition in method body https://srb.help/2001
707817 |class REXML::Validation::ValidationException < RuntimeError
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707829: dynamic constant assignment https://srb.help/2001
707829 | DEFAULT_ENCODING = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707830: dynamic constant assignment https://srb.help/2001
707830 | DEFAULT_STANDALONE = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707831: dynamic constant assignment https://srb.help/2001
707831 | DEFAULT_VERSION = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^
问题
对如何前进有什么建议吗?一种预感是我们需要迁移到 :zeitwerk
来解决这个问题,但这对我们来说是一个相当大的重构,所以我犹豫是否要探索它而不确认这是导致此失败的潜在根源。
编辑:此补丁的一个变体有 now been upstreamed into Sorbet 并且将在版本 >= 0.5.5911 中可用。对于使用这些版本的任何人,此答案不再相关。
我怀疑您看到的错误是由任何 Rails 配置引起的。您从 reflection.json.err
发布的行也没有显示任何真正的错误。
看起来您使用的是 Ruby 2.7,所以我怀疑您看到的错误是因为在 2.7 中参数转发是如何通过 def foo(...)
方法定义完成的。在运行时,这些在 Ruby 中变成 def foo(**, &&)
,当 Sorbet 尝试生成参数名称时,它失败了,因为 *
和 &
不是有效的参数名称。
您可以尝试使用我在下面包含的差异来修补 sorbet
gem 中的相关方法:
diff --git a/lib/serialize.rb b/lib/serialize.rb
index aec19ccb2..301793856 100644
--- a/lib/serialize.rb
+++ b/lib/serialize.rb
@@ -337,6 +337,14 @@ class Sorbet::Private::Serialize
uniq += 1
end
end
+
+ # Sanitize parameter names that are not valid
+ name = name.to_s.gsub(/[^a-zA-Z0-9_]/) do
+ result = '_' + (uniq == 0 ? '' : uniq.to_s)
+ uniq += 1
+ result
+ end
+
[kind, name]
end
end
您可以使用 bundle open sorbet
在您的编辑器中打开作为 Gemfile
的一部分安装的 sorbet
gem,应用上面的差异和 re-run隐藏定义生成器。如果这解决了您的问题,我很乐意将其公关到上游,以便在下一个冰糕版本中获得它。
上下文
- 我们的团队最近升级到 rails 6(从 5.2)。据我所知,到那时为止一切都运行良好。
- 我们的文件结构有点不寻常,所以我们选择使用
:classic
rails 加载程序而不是:zeitwerk
问题
每当我们 运行 srb rbi hidden-definitions
现在我们得到以下内容:
Got LoadError when trying to get nested name Tilt::PandocTemplate
Got LoadError when trying to get nested name Tilt::AsciidoctorTemplate
Got LoadError when trying to get nested name Tilt::CreoleTemplate
Got LoadError when trying to get nested name Tilt::LessTemplate
Got LoadError when trying to get nested name Tilt::LiquidTemplate
Got LoadError when trying to get nested name Tilt::LiveScriptTemplate
Got LoadError when trying to get nested name Tilt::MarkabyTemplate
Got LoadError when trying to get nested name Tilt::PrawnTemplate
Got LoadError when trying to get nested name Tilt::RadiusTemplate
Got LoadError when trying to get nested name Tilt::RedClothTemplate
Got LoadError when trying to get nested name Tilt::RstPandocTemplate
Got LoadError when trying to get nested name Tilt::TypeScriptTemplate
Got LoadError when trying to get nested name Tilt::WikiClothTemplate
Got LoadError when trying to get nested name Tilt::YajlTemplate
Naming WebConsoleGot NameError when trying to get nested name WebConsole::SourceLocation_
Generating /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi with 20603 modules and 305 aliases
Printing your code's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/from-source.json
Printing /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi's symbol table into /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json
Traceback (most recent call last):
5: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:237:in `<main>'
4: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:224:in `main'
3: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/bin/srb-rbi:232:in `block in make_step'
2: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:38:in `main'
1: from /usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:47:in `main'
/usr/local/var/rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/sorbet-0.5.5891/lib/hidden-definition-finder.rb:151:in `write_constants': /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi had unexpected errors. Check this file for a clue: /var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.json.err (RuntimeError)
reflection.json.err(错误指向的地方)散落着无数错误,看起来都像这样:
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707623: dynamic constant assignment https://srb.help/2001
707623 | REFERENCE = ::T.let(nil, ::T.untyped)
^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707624: dynamic constant assignment https://srb.help/2001
707624 | SETUTITSBUS = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707625: dynamic constant assignment https://srb.help/2001
707625 | SLAICEPS = ::T.let(nil, ::T.untyped)
^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707626: dynamic constant assignment https://srb.help/2001
707626 | SPECIALS = ::T.let(nil, ::T.untyped)
^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707627: dynamic constant assignment https://srb.help/2001
707627 | SUBSTITUTES = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707628: dynamic constant assignment https://srb.help/2001
707628 | VALID_CHAR = ::T.let(nil, ::T.untyped)
^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707629: dynamic constant assignment https://srb.help/2001
707629 | VALID_XML_CHARS = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707618: class definition in method body https://srb.help/2001
707618 |class REXML::Text < REXML::Child
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707801: class definition in method body https://srb.help/2001
707801 |class REXML::UndefinedNamespaceException < REXML::ParseException
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707813: module definition in method body https://srb.help/2001
707813 |module REXML::Validation
^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707817: class definition in method body https://srb.help/2001
707817 |class REXML::Validation::ValidationException < RuntimeError
^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707829: dynamic constant assignment https://srb.help/2001
707829 | DEFAULT_ENCODING = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707830: dynamic constant assignment https://srb.help/2001
707830 | DEFAULT_STANDALONE = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^^^^
/var/folders/w4/01z4c79j22l59fhcgyl43f8w0000gn/T/d20200911-19233-vy4tg3/reflection.rbi:707831: dynamic constant assignment https://srb.help/2001
707831 | DEFAULT_VERSION = ::T.let(nil, ::T.untyped)
^^^^^^^^^^^^^^^
问题
对如何前进有什么建议吗?一种预感是我们需要迁移到 :zeitwerk
来解决这个问题,但这对我们来说是一个相当大的重构,所以我犹豫是否要探索它而不确认这是导致此失败的潜在根源。
编辑:此补丁的一个变体有 now been upstreamed into Sorbet 并且将在版本 >= 0.5.5911 中可用。对于使用这些版本的任何人,此答案不再相关。
我怀疑您看到的错误是由任何 Rails 配置引起的。您从 reflection.json.err
发布的行也没有显示任何真正的错误。
看起来您使用的是 Ruby 2.7,所以我怀疑您看到的错误是因为在 2.7 中参数转发是如何通过 def foo(...)
方法定义完成的。在运行时,这些在 Ruby 中变成 def foo(**, &&)
,当 Sorbet 尝试生成参数名称时,它失败了,因为 *
和 &
不是有效的参数名称。
您可以尝试使用我在下面包含的差异来修补 sorbet
gem 中的相关方法:
diff --git a/lib/serialize.rb b/lib/serialize.rb
index aec19ccb2..301793856 100644
--- a/lib/serialize.rb
+++ b/lib/serialize.rb
@@ -337,6 +337,14 @@ class Sorbet::Private::Serialize
uniq += 1
end
end
+
+ # Sanitize parameter names that are not valid
+ name = name.to_s.gsub(/[^a-zA-Z0-9_]/) do
+ result = '_' + (uniq == 0 ? '' : uniq.to_s)
+ uniq += 1
+ result
+ end
+
[kind, name]
end
end
您可以使用 bundle open sorbet
在您的编辑器中打开作为 Gemfile
的一部分安装的 sorbet
gem,应用上面的差异和 re-run隐藏定义生成器。如果这解决了您的问题,我很乐意将其公关到上游,以便在下一个冰糕版本中获得它。