Context
Our team recently upgrade to rails 6 (from 5.2). AFAIK, things were working pretty well up to that point.
We have a slightly unconventional file structure so we opted to use the :classic rails loader instead of :zeitwerk
Problem
Whenever we run srb rbi hidden-definitions now we get the following:
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 (which the error points is to) is littered with countless errors that all look something like this:
/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)
^^^^^^^^^^^^^^^
Question
Any suggestions on how to move forward? One hunch is that we need to migrate to :zeitwerk to resolve this, but that's a pretty large refactor for us so I'm hesitant to explore that without confirming that that is a potential source for this failure.
EDIT: A variant of this patch has now been upstreamed into Sorbet and will be available in versions >= 0.5.5911. For anyone using those versions, this answer is no longer relevant.
I doubt that the error you are seeing is caused by any Rails configuration. The lines that you have posted from reflection.json.err do not show any real errors, either.
It looks like you are on Ruby 2.7, so I suspect that the error you are seeing is because of how the argument forwarding is done in 2.7 via def foo(...) method definitions. At runtime these turn into def foo(**, &&) in Ruby, and when Sorbet tries to generate the argument names, it fails, since * and & are not valid argument names.
You can try to patch the relevant method in sorbet gem using the diff I include below:
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
You can use bundle open sorbet to open the sorbet gem installed as part of your Gemfile in your editor, apply the diff above and re-run the hidden definitions generator. If that solves your problem, I'd be happy to PR it upstream to get it in the next sorbet release.
Related
I have a view that ajax-loads the same partial a number of times. Each one contains the result of a rather extensive calculation which takes a number of seconds. On my machine, about 3 times out of 20, instead of the partial I get the error message "Unable to autoload constant Answers::Node::Questions::KurzSinglePunch... expected .../app/models/answers/node/questions/kurz_single_punch.rb to define it" (I shortened the text and the path for legibility). The file is obviously there, since in 17 of 20 cases it is found, and the partial displays correctly in these cases.
In case this is relevant, I use Puma in single mode on a six-year-old Mac running OS 11.6.
This is the topmost part of the error message:
LoadError in KurzReportsController#company Unable to autoload constant Answers::Node::Questions::KurzSinglePunch,
expected /Users/marion/Documents/Projekte/myproject/app/models/answers/node/questions/kurz_single_punch.rb to define it
Extracted source (around line #511):
#509 else
#510 require_or_load(expanded, qualified_name)
*511 raise LoadError,
"Unable to autoload constant #{qualified_name}, expected #{file_path} to define it" unless from_mod.const_defined?(const_name, false)
#512 return from_mod.const_get(const_name)
#513 end
#514 elsif mod = autoload_module!(from_mod, const_name, qualified_name, path_suffix)
Extracted source (around line #195):
#193 def const_missing(const_name)
#194 from_mod = anonymous? ? guess_for_anonymous(const_name) : self
*195 Dependencies.load_missing_constant(from_mod, const_name)
#196 end
#197
#198 #
We assume that the name of the module reflects the nesting
Extracted source (around line #285):
#283 constant.const_get(name)
#284 else
*285 candidate = constant.const_get(name)
#286 next candidate if constant.const_defined?(name, false)
#287 next candidate unless Object.const_defined?(name)
#288 Rails.root: /Users/marion/Documents/Projekte/myproject
Application Trace app/exporters/kurz_report_extractor.rb:63:
in `infos_for_question_id' app/exporters/kurz_report_extractor.rb:59:
in `block in build_survey_hash' app/exporters/kurz_report_extractor.rb:59:
in `map' app/exporters/kurz_report_extractor.rb:59:
in `build_survey_hash' app/exporters/kurz_report_extractor.rb:15:
in `initialize' app/controllers/kurz_reports_controller.rb:27:
in `new' app/controllers/kurz_reports_controller.rb:27:
in `block in company' app/controllers/kurz_reports_controller.rb:25:
in `each' app/controllers/kurz_reports_controller.rb:25:in `company'
After that there is a long section with a Framework trace.
How can it be that Rails is sometimes unable to find this file? And how can I fix this?
I need to import one of my classes in one of my scaffolding views, this used to work in Grails 2 but now appears broken under 5.
I've tried both the GSP and JSP way of importing and both result with the same exception.
The error is as follows..
Message
Request processing failed; nested exception is groovy.lang.GroovyRuntimeException: Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed: GStringTemplateScript3.groovy: 3: Unexpected input: '# page import' # line 3, column 13. """; # page import="tst.Customer" ; ^ 1 error
Caused by
Failed to parse template script (your template may contain an error or be trying to use expressions not currently supported): startup failed: GStringTemplateScript3.groovy: 3: Unexpected input: '# page import' # line 3, column 13. """; # page import="tst.Customer" ; ^ 1 error
Thank you,
I was just playing with records, and am stuck trying to write a function that works with records. I think the problem is how to read the record definition into my module file.
The reocords.hrl file:
% Modeling a todo list
-record(todo, {status=reminder, who=joe, text}).
And then the use_records.erl file:
%% Use the records defined in "records.hrl"
-module(use_records).
-export([todo_to_tuple/1]).
rr("records.hrl").
todo_to_tuple(#todo{who=W, text=T} = R) -> {W, T}.
When I try to compile it, I get:
24> c(use_records).
use_records.erl:5: variable 'T' is unbound
use_records.erl:5: variable 'W' is unbound
use_records.erl:5: record todo undefined
use_records.erl:5: Warning: variable 'R' is unused
error
The error is the same if I remove the rr("records.hrl") line. So I suppose the real issue is being able to read the record definition (or not?). Please help!
rr/1 is used include record definition only in the shell.
In order to include record definition in your code use:
-include("records.hrl")
I am able to launch new instance at AWS from Ruby on Rails application (Chef::Knife::Ec2ServerCreate.new()). Works fine till I try to set JSON attributes. When I set them from command line and invoke knife.bat, it works.
Looking at ec2_server_create shows that command line option --json-attributes is mapped to symbol :json_attributes. I tried to set it using following code:
Chef::Config[:knife][:json_attributes] = "{'NodeName' : 'Node001'}"
and I get error:TypeError (no implicit conversion of Symbol into Integer):
As soon as I comment this single line, instance is created, registered with chef server and recipe is running.
Any suggestion how to set json attributes of first chef-client run?
PS
Sample code shows constant value for attribute, but actual value would be dynamically created.
Error message and code line where error occurs:
/chef/knife/core/bootstrap_context.rb:188:in `[]=': no implicit conversion of Symbol into Integer (TypeError)
Looking into source you can find:
def first_boot
(#config[:first_boot_attributes] || {}).tap do |attributes|
if #config[:policy_name] && #config[:policy_group]
attributes[:policy_name] = #config[:policy_name]
attributes[:policy_group] = #config[:policy_group]
else
attributes[:run_list] = #run_list #THIS LINE CAUSES EXCEPTION
end
attributes.merge!(:tags => #config[:tags]) if #config[:tags] && !#config[:tags].empty?
end
end
I set run list.
The issue is that json_attributes needs to be a hash, not a string. It isn't the #run_list that is failing, it is "{'NodeName' : 'Node001'}"[:run_list] which when you see in on place is probably a bit clearer.
ActionView::Template::Error (PG::UndefinedFunction: ERROR: operator
does not exist: double precision ~~ unknown
2016-04-10T23:45:59.506005+00:00 app[web.1]: LINE 1: ... =
"trackers"."category_id" WHERE (categories.tag LIKE '1.%'...
this is the error i get when i try to run this line of code here
Tracker.group(:category_id).joins(:category).where('categories.tag LIKE ? AND user_id = ?', "#{tag.to_i}.%", current_user.id)
tag is of type float, and i typecast it to an integer in order to check for tags 1.1, 1.2, 1.3 etc
so in the example above I type cast tag with value 1.0 to be 1, so i can search for tags that are like 1.1, 1.2 etc
I am using postgres on heroku that gives this error. locally i use sqlite3 and it works just fine.
how can i overcome this?
Since you're in rails, sort out the dynamic-ness in rails first then send that to the ORM. The syntax you provided already accepts any parameters (eg: WHERE tag between ? and ?), so before you request the data from the ORM, sort out in rails the high and lows. The query is already setup for something to be dynamic.